關於隨機數生成

2021-04-17 13:10:19 字數 1364 閱讀 9263

很多學計算機的學生大學四年學下來連隨機數是怎麼產生的都弄不明白,更有甚者連隨機函式怎麼呼叫都搞不清楚,這不能不說是一種悲哀。

嗯,現在讓我們一起使這種悲哀成為歷史吧^_

^。首先我們要搞清楚乙個概念,生成單個的隨機數是沒有意義的,我們所說的隨機數生成,其實都是生成乙個隨機序列。鑑於人們通常對具體的做法比對分析要感興趣,我會先給出一系列隨機數生成演算法,後面我會對這些演算法和其它命題進行稍稍深入的討論。

要找到真正的隨機數**很困難,象離子輻射事件的脈衝檢測器,氣體放電管和帶洩露的電容,我們不可能給每台需要產生隨機數的電腦配這麼一套裝置,況且這些東東產生的數值的隨機性和精確性都有問題。所以我們只能考慮通過某種演算法來產生隨機數。演算法都是確定的,因此我們無法產生真正統計隨機的數值串行,但是,如果演算法很好,所得的序列就可以通過許多隨機性測試,這些數就是所謂的偽隨機數了。

實現,我們的m當然不能超過32bit,幸好剛好有乙個滿足上述條件的很方便的素數2^31

-1給我們用,於是產生函式就變成了xn+1

=( axn) mod ( 2^

31– 

1)。在超過20億個a的可選取值中,只有很少的幾個可以滿足上述所有條件,其中之一就是a =7

^5=16807

...

這種產生器得到了廣泛的使用和比其它產生器都徹底的測驗,其產生的隨機數有在分布上有很好的特性,但是卻不具備良好的不可**性。所以我們在使用時往往會以系統時鐘(模m)或系統時鐘與隨機數的和(模m)作為種子來重新啟動序列,這也是現在絕大多數隨機數產生器的做法。

另一種產生偽隨機數序列的方法就是使用加密邏輯,通過加密演算法的雪崩效應,輸入的每一位改變就會造成輸出的巨大改變,並且假如金鑰被妥善儲存的話從序列中前面的數推出後面的數在計算上是不可行的,於是我們可以使用乙個簡單的累加器來作為輸入,得到的隨機序列可以直接使用(當然也可以把系統時間等等因素考慮進去作為輸入來產生更隨機的序列,不過這通常是沒有必要的),這種方法常常用來產生會話金鑰或是現時。具體採用的加密邏輯和運算方式有很多,這裡就不一一介紹了,大家感興趣可以找本密碼學的書來看看。

在密碼學領域裡比較流行的一種產生安全的偽隨機數的方法是bbs產生器,它用其研製者的名字命名(blum blum shub,不是我們經常灌水的那個bbs),它的密碼編碼強度據說具有最強的公開證明。首先,我們找兩個大素數p和q,要求它們被4除都餘3,令n 

=p×q,再選擇乙個隨機數s,使s與n互素,然後我們通過如下演算法產生一系列位元bi:

x0 =(s

^2)mod n,

fori =1

to ∞

xi =(xi-1

^2)mod n

bi =xi mod 

2每次迭代都只取出最低位的bit。可以看出bbs產生隨機數的過程非常複雜,運算量很大,嗯,這就是為安全性付出的代價-_

-b。

關於隨機數生成

c 隨機數生成函式rand 實質生成偽隨機數列。為生成更加隨機的數列,需要srand unsigned num 來播種。常用方式srand unsigned time null 增加標頭檔案 生成 a,b 之間的隨機整數的方法 1 rand b a 1 a 2 a b rand rand max 兩...

關於隨機數生成

涉及到skip lists的時候,基本上概率會選擇1 2,那麼需要多次生成0 1的隨機數。由於要多次生成隨機數,而隨機數的生成會極大的影響程式的執行效率。所以想到可不可以通過生成更大的隨機數來降低效率。比如兩次需要0 1的隨機數,可以通過一次0 3的隨機數m來代替。m 1和m 1 1 分別表示兩個隨...

隨機生成隨機數

現畫乙個command命令按鈕,進行貼上。private sub command1 click show me scale 0,0 18,8 me.auto redraw true me.draw mode 2 circle 3,4 3,vb red me.auto redraw false lin...