1:/dev/urandom和/dev/random是什么
這兩個文件記錄Linux下的熵池,所謂熵池就是當前系統下的環境噪音,描述了一個系統的混亂程度,環境噪音由這幾個方面組成,如內存的使用,文件的使用量,不同類型的進程數量等等,剛開機的時候系統噪音會較小。在這兩個設備的差異在於:/dev/random的random pool依賴於系統中斷,因此在系統的中斷數不足時,/dev/random設備會一直封鎖,嘗試讀取的進程就會進入等待狀態,直到系統的中斷數充分夠用, /dev/random設備可以保證數據的隨機性。/dev/urandom不依賴系統的中斷,也就不會造成進程忙等待,但是數據的隨機性也不高。
2:獲取/dev/urandom和/dev/random中的值
command:dd count=1 ibs=1024 if=/dev/urandom >/dev/null
command:dd count=1 ibs=1024 if=/dev/random >/dev/null
可以看見/dev/urandom生成隨機數的速度要快很多,一般就使用/dev/urandom獲取隨機數。
3:如何利用/dev/urandom生成隨機數
3.1 srand()和rand()
這兩個函數是Linux下生成隨機數的函數(unsigned long的隨機數),rand()函數返回的隨機數位於0到RAND_MAX之間,因為這之間的距離很長,所以從中取出一段來可以被認為是隨機數,哪取出一段來的起始位置是哪里呢?這個起始位置也叫做隨機種子,這個時候srand()函數就派上用場了,它就是用來決定從哪里開始取的,如果rand()之前沒有使用srand()設置隨機種子,就默認隨機種子為1,而且下一次再調用rand()取出的隨機數和上次一樣,所以要每次取出不一樣的隨機數就需要每次rand()之前調用srand()設置和上次不同的隨機種子。
3.2 實例
unsigned long random_xid(void) { static int initialized; if (!initialized) { int fd; unsigned long seed; fd = open("/dev/urandom", 0); if (fd < 0 || read(fd, &seed, sizeof(seed)) < 0) { LOG(LOG_WARNING, "Could not load seed from /dev/urandom: %s", strerror(errno)); seed = time(0); } if (fd >= 0) close(fd);
//設置隨機種子 srand(seed);
//下次取同樣的隨機數 initialized++; } return rand(); }
實例是udhcp源碼中dhcp client生成xid的過程(因為xid在一次事務中是不變的所以只取一次隨機數)。