2014-10-18 72 views
7

General purpose random number generation的啓發我決定執行我自己的測試以查看rand()出了什麼問題。使用這個程序:蘭特()真的很糟糕嗎?

srand(time(0)); 
for (int i = 0; i < 1000000; ++i) 
{ 
    std::cout << rand() % 1000 << " "; 
} 

我使用的命令加載它在八度:

S = load("test.txt") 
hist(S) 

,得到了這樣的結果:

result

對我來說,結果似乎是相當制服。我預計結果會更加傾斜。我做錯了嗎?

+2

蘭特主要是不好的,因爲:'是實現定義RAND_MAX',以及例如在視覺工作室它僅僅是2^16; rand是全局的,這意味着如果別人以外的其他人調用srand,它可能會搞砸你的代碼。如果您有C++ 11編譯器,請考慮使用其中一個RNG – Creris 2014-10-18 13:32:35

+0

根據具體實現,rand()可以在其低位具有較低的熵。如果你做了'rand()%4',在一些實現中這是非常不一致的。這就是爲什麼在這種情況下通常推薦使用(如果使用'rand()')寫入'rand()/(RAND_MAX/4)'的原因。 – leemes 2014-10-18 13:33:38

+6

* rand()真的很糟嗎?* YES! – 2014-10-18 13:39:13

回答

8

在你的問題中的測試並不真正測試隨機性。它所做的只是確保數字均勻分佈。這是一個必要但不是充分的條件:有很多其他的方式可以使隨機數發生器不足。

例如,如果我給你返回的數字0,1,2,...,999在一個循環中,它也會通過測試的功能。然而,它顯然會失去任何合理的隨機性定義。

要看到數量如何隨機生成在實踐中進行測試,看看

對於rand()討論具體而言,退房rand() Considered Harmful

+0

http://xkcd.com/221/編輯:你的第二個鏈接dilbert更好。 – 2014-10-18 13:43:43

1

你是不是考慮的重要一點是生成的隨機序列是如何預測的是。當使用time()作爲隨機種子時,如果攻擊者知道 - 或多或少 - 當種子生成時,他可以很容易地重現你的整個隨機序列。

這就是爲什麼真正的隨機源是需要的,假設你使用這些隨機數的任何與安全有關。

當安全真的很重要,你還想要得到的每個從真隨機源的數字,而不依賴於PRNG的。更慢但更安全。

0

這取決於你的目的,提供rand()是簡單的手頭上使用可接受的分佈可能性,它不適合加密的目的,也不是物理模擬的目的。如果你想要一個加密級別或進行物理模擬,這不是一個好的選擇,你可能需要得到一個特殊的實現。
沒有real計算機程序產生的隨機性呢。

+1

關於最後一句,你排除這些設備:http://en.wikipedia.org/wiki/Hardware_random_number_generator? – NPE 2014-10-18 14:36:40

+0

@NPE感謝您的好意。 – 2014-10-18 15:40:32

相關問題