linux shell實現隨機數多種方法(date,random,uuid)

在平常生活中,隨機數實際上常常遇到,想丟骰子,抓鬮,還有抽籤。呵呵,很是簡單就能夠實現。那麼在作程序設計,真的要經過本身程序設計出隨機數那還真的不簡單了。如今不少都是操做系統內核會提供相應的api,這些原始參數是獲取一些計算機運行原始信息,如內存,電壓,物理信號等等,它的值在一個時間段能夠保證是惟一的了。好了,廢話我就不說了。呵呵。php


   shell腳本程序咱們有那些得到隨機數方法呢?linux


 


1、經過時間得到隨機數(date)算法


這個也是咱們常常用到的,能夠說時間是惟一的,也不會重複的,從這個裏面得到同一時間的惟一值。適應全部程序裏面了。shell


例子:數據庫

[chengmo@centos5  shell]$ date +%s
1287764773
#得到時間戳,當前到:1970-01-01 00:00:00 相隔的秒數
#若是用它作隨機數,相同一秒的數據是同樣的。在作循環處理,多線程裏面基本不能知足要求了。
 
[chengmo@centos5  shell]$ date +%N
738710457
#得到當前時間的納秒數據,精確到億分之一秒。
#這個至關精確了,就算在多cpu,大量循環裏面,同一秒裏面,也很難出現相同結果,不過不一樣時間裏面還會有大量重複碰撞
 
[chengmo@centos5  shell]$ date +%s%N
1287764807051101270
#這個能夠說比較完美了,加入了時間戳,又加上了納秒

經過上面說明,用它來作隨機數的基數了,接下來咱們看怎麼樣得到一段數據內怎麼樣得到隨機數。windows

#!/bin/sh
 
#寫個隨機函數,調用方法random min max 
#在min 與 max直接得到隨機整數
#copyright chengmo QQ:8292669
 
 
#得到隨機數返回值,shell函數裏算出隨機數後,更新該值
function random()
{
    min=$1;
    max=$2-$1;
    num=$(date +%s+%N);
    ((retnum=num%max+min));
    #進行求餘數運算便可
    echo $retnum;
    #這裏經過echo 打印出來值,而後得到函數的,stdout就能夠得到值
    #還有一種返回,定義全價變量,而後函數改下內容,外面讀取
}
 
#獲得1-10的seq數據項
for i in {1..10};
do 
    out=$(random 2 10000);
    echo $i,"2-10000",$out;
done;

看看運行結果:centos

[chengmo@centos5  shell]$ sh testrandom.sh
api

1,2-10000,5600服務器

2,2-10000,5295網絡

3,2-10000,3432

4,2-10000,3148

5,2-10000,9041

6,2-10000,4290

7,2-10000,2380

8,2-10000,9009

9,2-10000,5474

10,2-10000,3664


一個循環裏面,獲得值各不相同。


這個是咱們經常使用方法,適應各類語言,是一個通用算法,就算服務器不提供,某時刻相同惟一數據標記,咱們也能夠經過這種方法,作本身的僞隨機數。下面還有更簡單方法呢,不要咱們本身作了。


二、經過內部系統變量($RANDOM)


其實,linux已經提供有個系統環境變量了,直接就是隨機數,哈哈,以爲剛學習方法,是否是白費了!!

[chengmo@centos5  shell]$ echo $RANDOM
10918
[chengmo@centos5  shell]$ echo $RANDOM
10001
 
#連續2次訪問,結果不同,這個數據是一個小於或等於5位的整數


可能有疑問了,若是超過5位的隨機數怎麼獲得呢?


呵呵,加個固定10位整數,而後進行求餘,跟例1 同樣了。接下來的例子又是咱們自立更生作了。


三、經過系統內部惟一數據生成隨機數(/dev/random,urandom)


咱們知道dev目錄下面,是linux一些默認設備,它給咱們感受就是放的是鍵盤,硬盤,光驅等設備的對應文件了。 其實linux有些設備很特殊,有特殊用途。前面咱們說到的:/dev/[udp|tcp]/host/port比較特殊吧。呵呵,有扯遠了。


/dev/random設備,存儲着系統當前運行的環境的實時數據。它能夠看做是系統某個時候,惟一值數據,所以能夠用做隨機數元數據。咱們能夠經過文件讀取方式,讀得裏面數據。/dev/urandom這個設備數據與random裏面同樣。只是,它是非阻塞的隨機數發生器,讀取操做不會產生阻塞。


實例:

[chengmo@centos5  shell]$ head -1 /dev/urandom
ãņù…•KTþçanVÕã¹Û&¡õ¾「ô2íùU「 žF¦_ ÿ」†mEðûUráÏ=J¯TŸA•ÌAÚRtÓ
 
#讀一行,怎麼是亂碼呢?其實它是經過二進制數據保存實時數據的,那麼咱們怎麼樣把它變成整型數據呢?
 
 
[chengmo@centos5 ~/shell]$ head -200 /dev/urandom | cksum
1615228479 50333
#因爲urandom的數據是很是多,不能直接經過cat讀取,這裏取前200行,其實整個數據都是變化的,取多少也同樣是惟一的。
#cksum 將讀取文件內容,生成惟一的表示整型數據,只有文件內容不變,生成結果就不會變化,與php crc函數
 
[chengmo@centos5  shell]$ head -200 /dev/urandom | cksum | cut -f1 -d" "
484750180
#cut 以」 「分割,而後獲得分割的第一個字段數據



獲得整型數據,而後,相似一的方法就能夠得到到隨機數了。 題外話:在程序裏面,咱們常常md5獲得惟一值,而後是字符串的,若是想表示成整型方式,能夠經過crc函數.crc是循環冗餘校驗,相同數據經過運算,都會獲得一串整型數據。如今這種驗證應用很廣。詳細要了解,能夠參考:crc.


下面還有個方法,直接從設備讀取生成好的uuid碼。


 


四、讀取linux 的uuid碼


在提到這個以前,有個概念,就是什麼是uuid呢?


UUID碼全稱是通用惟一識別碼 (Universally Unique Identifier, UUID),它 是一個軟件建構的標準,亦爲自由軟件基金會 (Open Software Foundation, OSF) 的組織在分佈式計算環境 (Distributed Computing Environment, DCE) 領域的一部份。


 


UUID 的目的,是讓分佈式系統中的全部元素,都能有惟一的辨識信息,而不須要經過中央控制端來作辨識信息的指定。如此一來,每一個人均可以建立不與其它人衝突的 UUID。在這樣的狀況下,就不需考慮數據庫建立時的名稱重複問題。它會讓網絡任何一臺計算機所生成的uuid碼,都是互聯網整個服務器網絡中惟一的。它的原信息會加入硬件,時間,機器當前運行信息等等。


UUID格式是:包含32個16進位數字,以「-」鏈接號分爲五段,形式爲8-4-4-4-12的32個字符。範例;550e8400-e29b-41d4-a716-446655440000  ,因此:UUID理論上的總數爲216 x 8=2128,約等於3.4 x 1038。 也就是說若每奈秒產生1兆個UUID,要花100億年纔會將全部UUID用完。


其實,你們作數據庫設計時候,確定據說過,guid(全局惟一標識符)碼,它實際上是與uuid相似,由微軟支持。 這裏編碼,基本有操做系統內核產生。你們記得把,在windows裏面,不管數據庫,仍是其它軟件,很容易獲得這個uuid編碼。


 


linux 的uuid碼


linux的uuid碼也是有內核提供的,在/proc/sys/kernel/random/uuid這個文件內。其實,random目錄,裏面還有不少其它文件,都與生成uuid有關係的。

[chengmo@centos5 ~/shell]$ cat /proc/sys/kernel/random/uuid
dff68213-b700-4947-87b1-d9e640334196
[chengmo@centos5 ~/shell]$ cat /proc/sys/kernel/random/uuid
7b57209a-d285-4fd0-88b4-9d3162d2e1bc
#連續2次讀取,獲得的uuid是不一樣的
 
[chengmo@centos5 ~/shell]$ cat /proc/sys/kernel/random/uuid| cksum | cut -f1 -d" "
2141807556
#同上方法獲得隨機整數


這是linux下面,幾種常見活動隨機數整數方法,除了第一個是不一樣外,其實後3個,產生隨機碼的僞數據來源,都與/dev/random設備有關係。只是它們各自呈現不一樣而已。若是你還有更多其它方法,請給我消息,與你們分享

相關文章
相關標籤/搜索