2010-12-14 19 views
11

由於計算機不能選擇隨機數(他們可以嗎?)這個隨機數如何實際生成。例如在C#中,我們說,如何在運行時生成一個隨機數?

Random.Next() 

裏面會發生什麼?

+5

搜索 - 已經有幾十個這個問題的答案。 – RogerG 2010-12-14 15:30:24

+0

這裏是另一個話題,包括要求隨機random.next的as3實現:http://stackoverflow.com/questions/3930291/actionscript-3-implementation-of-random-next也有代碼片段 – 2010-12-14 15:30:36

+1

@RogerG>你有鏈接分享?因爲我沒有看到任何...... @hacticks>非常感謝 – naveen 2010-12-14 15:40:02

回答

14

您可以結帳this article。根據documentation,.NET中使用的具體實現基於Donald E. Knuth的減法隨機數生成器算法。有關更多信息,請參閱D. E. Knuth. "The Art of Computer Programming, volume 2: Seminumerical Algorithms". Addison-Wesley, Reading, MA, second edition, 1981

+1

這是一篇非常好的文章---它包含一些指向源代碼的鏈接,顯示很少有PRNGs,這很棒。 +1 – 2010-12-14 15:31:44

+0

非常感謝......非常全面 – naveen 2010-12-14 15:40:52

2

Random類是pseudo-random number generator

它基本上是一個非常長但確定性的重複序列。 「隨機性」來自不同的位置。通過爲隨機數發生器選擇一個seed來指定從哪裏開始,並且可以例如通過使用系統時間或從另一個隨機源獲得隨機種子來完成。 default Random constructor使用系統時間作爲種子。

實際的算法來生成數字序列中MSDN進行了說明:

當前實現Random類是基於唐納德·E·Knuth的消減隨機數生成算法。欲瞭解更多信息,請參閱D. E. Knuth。 「計算機編程的藝術,第2卷:研究數學算法」。 Addison-Wesley,馬薩諸塞州雷丁市,第二版,1981年。

+0

所以,我們不希望將C#Random類用於加密函數,那麼,它聽起來像?我認爲會有某種API可用於獲取這些數字,或者需要通過P/Invoke使用Win32函數? – 2010-12-14 15:33:06

+1

@Michael Trausch:你可能想看看RandomNumberGenerator來代替加密的目的:http://msdn.microsoft.com/en-US/library/system.security.cryptography.randomnumbergenerator。aspx – 2010-12-14 15:39:11

0

我不知道更多的細節,但我知道的是種子是用來生成隨機數然後基於一些算法使用該種子獲得新的數字。

如果您根據同一種子獲得隨機數,它們將經常是相同的。

1

電腦使用pseudorandom number generators。從本質上講,他們通過從種子編號開始並在每次需要新的僞隨機數時通過算法迭代它。

這個過程當然是完全確定性的,所以給定的種子在每次使用時都會生成完全相同的數字序列,但生成的數字形成統計均勻分佈(近似),這很好,因爲在大多數情況下你需要的是隨機隨機性。

通常的做法是使用當前的系統時間作爲種子,但是如果需要更多的安全性,可以從諸如磁盤等待時間之類的物理源收集「熵」,以便生成更困難的種子預測。在這種情況下,您還需要使用cryptographically strong random number generator,如this

5

由於電腦不能選擇隨機數(可他們?)

正如其他人所指出的,「隨機」其實是僞隨機的。回答你的括號問題:是的,電腦可以選擇真正的隨機數字。這樣做比僞隨機數發生器的簡單整數算法昂貴得多,通常不是必需的。但有些應用程序的必須具有不可預測的真隨機性:密碼學和在線撲克立刻浮現在腦海。如果要麼使用可預測的僞隨機性來源,那麼攻擊者可以更容易地解密/僞造消息,作弊者可以找出誰的手中有什麼。

.NET加密類有methods that give random numbers suitable for cryptography或遊戲的錢是在線。至於它們是如何工作的:關於密碼強度隨機性的文獻是廣泛的;有關詳細信息,請查閱任何有關密碼學的優秀大學本科教科書。

專用硬件也存在獲得隨機位。如果您需要從大氣噪音中提取的隨機數字,請訪問www.random.org。

+2

所有基於計算機/邏輯的RNG都是僞隨機*,除非*它們具有真正的隨機源。隨機的來源就像放射性衰變。一些計算機硬件具有隨機數發生器,其具有處於不穩定狀態的晶體管並創建恆定的隨機比特流。僞隨機和隨機之間的區別是僞隨機的是確定性的,但是從許多來源獲取數據是非常難以預測的,並且即使你知道所有的來源,也是真正的隨機,你仍然不知道輸出直到它發生。 – Bengie 2010-12-14 16:28:52

+0

@Bengie:我相信加密類從按鍵定時等來源獲得它們的熵。這些都是隨機的,因爲你需要它們用於實際目的。 – 2010-12-14 18:00:15

+0

thanka很多eric .. – naveen 2010-12-15 06:40:49

4

Knuth涵蓋了非常好的隨機性主題。

我們並不很好地理解隨機。如何可以預測是隨機的?然而,僞隨機序列可以通過統計測試看起來是完全隨機的。

有三類隨機發生器,放大上面的評論。

首先,你有僞隨機數發生器,如果你知道當前的隨機數,很容易計算下一個數。如果發現一些數字,這可以很容易地對其他數字進行逆向工程。

然後,有加密算法,使這更難。我相信它們仍然是僞隨機序列(與上面的評論相反),但是有一個非常重要的特性,即知道序列中的一些數字並不能說明如何計算其餘部分。它的工作方式是加密程序傾向於對數字進行加密,以便如果一位發生改變,則每一位都有可能改變結果。

考慮一個簡單的模發生器(類似於C蘭特()一些實現方式中)

INT蘭特(){ 返回種子=種子* M + A; }

如果m = 0和a = 0時,這是具有周期1一個糟糕發生器:0,0,0,0,.... 如果m = 1和a = 1時,它也不太隨機看:0,1,2,3,4,5,6,...

但是,如果你選擇m和a是2^16左右的素數,那麼這將會很好地隨機跳轉,如果你隨便檢查。但是因爲兩個數字都是奇數,所以你會看到低位會切換,即數字交替出現奇數和偶數。不是一個好的隨機數發生器。而且由於在32位數中只有2^32個值,按照定義,至多在2^32次迭代後,您將再次重複該序列,使得顯而易見的是該生成器不是隨機的。

如果你認爲中間位是好的並且是混亂的,而低位不是隨機的,那麼你可以在其中幾個位置構建一個更好的隨機數生成器,並將各個位異或,這樣所有的位都覆蓋得很好。喜歡的東西:

(RAND 1()>> 8)^ RAND2()^(rand3()> 5)...

儘管如此,每個號碼翻轉保持同步,這使得這個預測的。如果你得到兩個連續的值,它們是相互關聯的,所以如果你繪製它們,你會在屏幕上看到線條。現在想象你有組合發生器的規則,所以順序值不是下一個值。 例如

v1 = rand1()>> 8^rand2()... v2 = rand2()>> 8^rand5()..

想象種子並不總是前進。現在,你開始做一些基於逆向工程難以預測的事情,並且順序更長。例如,如果每次計算rand1(),但每隔3次只提前一次rand2()中的種子,則組合它們的生成器可能不會重複的時間遠遠長於其中的任何一個。

現在想象你可以通過DES或其他一些加密算法將你的(相當可預測的)模數型隨機數發生器抽取出來。這將擾亂比特。

很明顯,有更好的算法,但這給你一個想法。 Numerical Recipes在代碼中實現了很多算法並進行了解釋。一個很好的技巧:在表中生成一個不是一個而是一個隨機值塊。然後使用一個獨立的隨機數發生器來選擇一個生成的數字,生成一個新數字並將其替換。這打破了相鄰數字對之間的任何關聯。

第三類是實際的基於硬件的隨機數生成器,例如基於大氣噪聲

http://www.random.org/randomness/

這是,按照目前的科學,真正隨機的。也許有一天我們會發現它服從一些基本的規則,但是目前我們無法預測這些價值,並且就我們而言它們是「真正」隨機的。

如果你想看到一些源代碼,boost庫具有斐波那契發生器的優秀C++實現,它是僞隨機序列的統治國王。

4

我就添加一個回答問題的第一部分(「能嗎?」部分).H

計算機可以產生(當然,產生可能不是完全準確字)隨機數(如在,不是僞隨機的)。具體地,通過使用通過專用硬件設備(例如基於噪聲產生隨機性)或通過使用環境輸入(例如硬盤時序,用戶輸入事件時序)獲得的環境隨機性。

但是,這對第二個問題沒有影響(這是Random.Next()的工作原理)。