堆栈指针是伪随机数的良好来源

时间:2016-07-28 15:13:34

标签: c++ c

例如:

int main()
{
  int p;

  ::std::cout << ::std::uintptr_t(&p) << ::std::endl;
}

这将始终如一地产生&#34;随机&#34;数字如果反复执行。类似的东西可以在C中完成。我没有看到任何关于它的事情。

4 个答案:

答案 0 :(得分:4)

我完全取决于你对随机数分布的要求。序列1,1,1,1,1,1,1,1是随机的吗?实际上很难说,但如果你对正态分布进行测试肯定会失败。伪随机数生成器专门设计用于匹配您希望从中获取的随机分布的属性。

如果你做了一些诡计以获得一个以前未知的数字(故意我不称之为随机),这个数字可能对你来说似乎是随机的,但很可能有你不会发现的模式。

TL; DR:写一个好的rng并不容易。如果需要随机数,请使用可用的那些。

答案 1 :(得分:4)

,否。

不能使用变量地址,未初始化变量的值等作为随机数的来源。

其中一些用途会让你直接获得“未定义行为”的票证,你的编译器可以在你的代码中执行可怕的,可怕的事情。

有些只是并非真正所有随机。

如果您想要随机数,请使用&lt;中提供的内容。 random&gt;如果您没有直接使用random_device(您可能不希望使用非加密数字),请确保正确播种您的生成器。

甚至不考虑rand() - 忘记它存在。太可怕了。

您应该使用std::seed_seq混合多个熵源,然后使用它来为发生器播种。假设您还包含其他更高质量的来源(尤其是seed_seq),将变量的地址作为 std::random_device输入中的一个输入就可以了。

答案 2 :(得分:4)

如果您的操作系统randomizes the stack address of your program,您可以从本地变量的地址中提取几个随机位。这些可能是高质量的随机位(如果你的操作系统很好),但只会有几个,因为:

  • 对齐有严格的要求(因此低位将是恒定的,而不是随机的)
  • 任何操作系统可能出于方便原因限制用户程序的地址空间(因此高位将保持不变)

所以这个方法并不好,因为它的结果很大程度上依赖于操作系统(作为一个极端的例子,用户可以禁用ASLR,你的随机数生成器将停止为该用户工作)。

答案 3 :(得分:3)

  • 作为随机数的来源,它非常糟糕,因为它对于一个严肃的对手来说是非常可预测的。正如其他人所说的那样,地址空间是有限的,满足int对齐要求的地址要少得多,最重要的是,程序加载到内存中的算法,如果没有记录,它至少不是为了随意而构建的。
  • 作为 entropy 的来源,它取决于操作系统。如果操作系统没有随机化,则会损害可读性 - 因为有人在阅读您的代码时可能会错误地认为您在此时添加了熵。如果操作系统确实随机化,它仍然不是一个很好的熵源,你必须将它与其他更好的来源结合起来进行补偿 - 这些必须完全独立于随机地址的熵源。

在任何情况下,这都假设您使用变量的地址(完全有效)而不是(未初始化时未定义的行为)。如果您调用未定义的行为,操作可能会丢弃所有熵。