無交互系統或工做站設備上的隨機數填充器

轉自 https://cloud.tencent.com/developer/article/1087417linux

 

通常生成隨機數,能夠用glibc提供的random()函數,不過這個是僞隨機的函數,因此通常會在使用使用random函數以前初始化種子:srandom(time()),或者使用srandom(getpid())。可是,兩次使用的種子相同的狀況下,會獲得相同的隨機數!簡單作一個實驗,使用同一個seed,兩次生成100個隨機數,它們是相同的數列!緣由也很簡單,經過相同的算法作hash或者移位或者加減,必然會獲得一樣的結果。 因此,/dev/random出現了。用來生成隨機數,避免生成相同的數列的隨機數!可是在使用dev random的時候,可能會遇到生成隨機數很是慢的狀況,若是隻是爲了解決問題,直接到第四步,若是但願看一下原理,能夠選擇從頭開始看。算法

分析: 1,dev random block 一個小實驗,期待生成不少的隨機數,使用shell命令:cat /dev/random > out。 然而,狀況並不是如此,很長的時間,只生成了幾個byte的數據。查一下緣由:shell

竟然sleep了。。ubuntu

2,stack 繼續分析,查看stack:centos

很顯然,不是cat進程本身主動調用了sleep或者yield,而是由於調用read讀取的時候,被block住了。dom

3,random_read_wait 有了地址,就好說了。使用命令:addr2line -e vmlinux -a 0xffffffff81513767來看看問題出在了哪裏: 在linux-4.0.4/drivers/char/random.c中:函數

好吧,須要被喚醒。因此找到wake_up_interruptible(&random_read_wait);這個函數在哪裏調用的,就能夠知道怎麼能夠觸發被喚醒了。google

 

4,haveged 在google的時候,極可能會提示安裝haveged這個包。 對於ubuntu:apt-get install haveged 對於centos:yum install -y haveged 安裝上了haveged包,果真能夠快速生成大量的隨機數了。 下載haveged的源代碼包:http://www.issihosts.com/haveged/haveged-1.9.1.tar.gzblog

可見,haveged使用死循環調用ioctl。找到對應的kernel代碼,發如今RNDADDENTROPY的時候,會喚醒 random_read_wait,進一步喚醒經過/dev/random獲取隨機數的進程。 那麼整個過程就分析完了。進程

相關文章
相關標籤/搜索