受General purpose random number generation的启发,我决定进行自己的测试,看看rand()出了什么问题。使用这个程序:
srand(time(0));
for (int i = 0; i < 1000000; ++i)
{
std::cout << rand() % 1000 << " ";
}
我使用命令在Octave中加载它:
S = load("test.txt")
hist(S)
得到了这个结果:
对我而言,结果看起来非常均匀。我预计结果会更加偏斜。我的测试错了吗?
答案 0 :(得分:11)
您问题中的测试并未真正测试随机性。它所做的就是确保数字均匀分布。这是一个必要但不充分的条件:随机数生成器有许多其他方法可能存在缺陷。
例如,如果我给你的函数在循环中返回数字0,1,2,...,999,它也会通过你的测试。然而,任何合理的随机性定义显然都会失败。
要了解在实践中如何测试随机数生成器,请查看
有关rand()
的具体讨论,请查看rand()
Considered Harmful。
答案 1 :(得分:1)
您不考虑的一个重点是生成的随机序列是多么可预测。 当使用time()作为随机种子时,如果攻击者知道 - 或多或少 - 生成种子时,他可以很容易地重现整个随机序列。
这就是为什么需要一个真正的随机源,假设您将这些随机数用于与安全相关的任何事情。
当安全真的很重要时,您还希望从真正的随机源中获取每个数字,而不依赖于PRNG。更慢但更安全。
答案 2 :(得分:0)
这取决于您的目的,所提供的rand()
对于具有可接受的分发可能性的现有使用来说是简单的,它不是为加密目的而设计的,也不是物理模拟目的。如果你想要一个加密级别或进行物理模拟,它不是一个好的选择,你可能必须得到一个特殊的实现。
计算机程序还没有产生真正的随机性。