2014-10-18 75 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

相关问题