2012-12-08 58 views
2

今天,我的朋友有一個想法,設置使用產生「使事情變得更加隨機」的僞隨機數的僞隨機數生成器多次的種子。「重置」僞隨機數發生器種子多次?

在C#中的一個例子:

// Initiate one with a time-based seed 
Random rand = new Random(milliseconds_since_unix_epoch()); 
// Then loop for a_number_of_times... 
for (int i = 0; i < a_number_of_times; i++) 
{ 
    // ... to initiate with the next random number generated 
    rand = new Random(rand.Next()); 
} 
// So is `rand` now really random? 
assert(rand.Next() is really_random); 

但我在想,這大概可以增加獲得正在使用的僞隨機數生成器的重複種子的機會。

  1. 會讓事情變得更加隨機,
  2. 進行循環,通過使用一定數量的種子,或
  3. 無助於隨機性(即既不增加也不減少)?

僞隨機數發生器的任何專家能給出一些詳細的解釋,以便說服我的朋友嗎?我很樂意在某些僞隨機數生成器算法中看到解釋更多細節的答案。

+0

ou ...你最好的選擇是(xkcd)擲骰一次,並簡單地使用它作爲一個常數。 Nahw只是開玩笑 - 計算機不能使隨機數字非常好。每個非僞隨機都使用外部(如物理測量)源來進行初始化和隨機...因此,對於正常的隨機數在應用程序中使用其他任何類似time.h(正如您已經這樣做)這樣的麻煩是不值得的。如果你真的需要隨機數,考慮使用硬件 – Najzero

+0

@Najzero嗯,只是想了解更多關於僞數字發生器的知識,所以我不會爲此得到一個核衰變檢測器。 :) –

+0

ffffshhh ...沒有承諾更多,一切或http://xkcd.com/221/ – Najzero

回答

5

有使用的僞隨機數三個基本層次。每個級別都包含在它下面的一個級別。

  1. 意外的數字,沒有特別的相關性擔保。這個級別的生成器通常會有一些對您而言可能很重要或者可能不重要的隱藏關聯。
  2. 具有已知非相關性的統計獨立數。這些通常是數值模擬所必需的。
  3. 密碼安全的數字,不能被猜測。當安全問題時,這些都是必需的。

這些都是確定性的。隨機數發生器是一種具有某種內部狀態的算法。一旦應用算法產生新的內部狀態和輸出數字。播種發電機意味着建立一個內部狀態;種子界面並不總是允許設置每個可能的內部狀態。作爲一個好的經驗法則,總是假定默認庫random()例程僅在最弱的級別1上運行。

要回答您的特定問題,問題(1)中的算法不能增加隨機性, (2)可能會減少它。因此,隨機性的期望嚴格低於一開始播種一次。原因來自短迭代週期的可能存在。爲函數F迭代週期是一對整數nk其中F^(n) (k) = k,其中指數是被施加的次數F數目。例如,F^(3) (x) = F(F(F(x)))。如果迭代週期較短,那麼隨機數字會比其他情況下的頻繁重複。在所提供的代碼中,迭代函數是對發生器進行種子處理,然後獲取第一個輸出。

要回答一個問題,你沒有聽問,但它是有關獲得這方面的一個理解,用毫秒計數器播種,使您的發電機故障3級,unguessability的考驗。這是因爲可能的毫秒數是加密小,這是一個已知的數量受到窮盡搜索。在撰寫本文時,2^50應該被認爲是密碼小的。 (因爲任何年份的密碼都很大,請找一位有信譽的專家。)現在,一個世紀的毫秒數大約是2 ^(41.5),所以不要爲了安全目的而依靠這種播種形式。因爲在entropy沒有增加

0

這不會使事情變得更加「隨機」。

我們的種子確定rand.next()爲我們提供了數字的隨機尋找,但完全確定順序。

反而使事情變得更隨機的,你的代碼定義一個映射,從您最初的種子到一些最後的種子,並給予相同的初始種子,你將永遠結束了相同的最終的種子。

嘗試使用此代碼玩,你會明白我的意思(也here is a link to a version you can run in your browser):

int my_seed = 100; // change my seed to whatever you want 
Random rand = new Random(my_seed); 
for (int i = 0; i < a_number_of_times; i++) 
{ 
    rand = new Random(rand.Next()); 
} 
// does this print the same number every run if we don't change the starting seed? 
Console.WriteLine(rand.Next()); // yes, it does 

這個最終種子的Random對象,就像任何其他的隨機對象。它只是需要更多的時間來創建它。

+0

又是如何使用當前的任何時間更少(如'milliseconds_since_unix_epoch()')? –

+0

是的,使用'milliseconds_since_unix_epoch()'是生成你的初始種子的正確方法。在你的代碼中,最終的隨機對象將有一個種子,它是這個初始種子的可預測轉換。我提供的代碼的目的是向您展示,通過執行這種可預測的轉換,您不會再向系統中引入更多的熵。 –

1

你的榜樣,不會增加隨機性。它只是從程序的執行時間導出的。

而不是使用基於當前時間的東西,電腦維護熵池,並與統計學隨機的(或至少,不可猜測)是數據建立起來。例如,網絡數據包之間的時間延遲或擊鍵,或硬盤讀取時間。

如果你想得到好的隨機數,你應該進入熵池。這些被稱爲Cryptographically secure pseudorandom number generators

在C#中,請參閱Cryptography.RandomNumberGenerator Class以獲取安全隨機數的正確方法。