在平常生活中,隨機數實際上常常遇到,想丟骰子,抓鬮,還有抽籤。呵呵,很是簡單就能夠實現。那麼在作程序設計,真的要經過本身程序設計出隨機數那還真的不簡單了。如今不少都是操做系統內核會提供相應的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設備有關係。只是它們各自呈現不一樣而已。若是你還有更多其它方法,請給我消息,與你們分享