是堆栈指针,是伪随机数的良好来源
is a stack pointer a good source of pseudo-random numbers
例如:
int main()
{
int p;
::std::cout << ::std::uintptr_t(&p) << ::std::endl;
}
如果重复执行,这将始终产生"随机"数字。类似的事情可以在C中完成。我看不到任何关于它的UB。
我非常依赖于您对随机数分布设置的要求。序列1,1,1,1,1,11,1,1,1是随机的吗?事实上很难说,但如果你对正态分布进行测试,它肯定会失败。伪随机数生成器是专门为匹配您想要从中获得的随机分布的属性而设计的。
如果你耍了一些花招来得到一个以前未知的数字(我故意不称之为随机),这个数字对你来说可能是随机的,但很可能有一些模式你根本没有发现。
TL;DR:要写出一个好的rng并不容易。如果您需要随机数字,请使用可用的数字。
如果操作系统将程序的堆栈地址随机化,则可以从本地变量的地址中提取几个随机位。这些可能是高质量的随机位(如果你的操作系统很好的话),但只有少数,因为:
- 对对齐有严格的要求(因此低位是恒定的,而不是随机的)
- 任何操作系统都可能出于方便的原因限制用户程序的地址空间(因此高位将是恒定的)
因此,这种方法并不好,因为它的结果严重依赖于操作系统(作为一个极端的例子,用户可以禁用ASLR,而您的随机数生成器将停止为该用户工作)。
无,无,无
您不能使用变量地址、未初始化变量的值等作为随机数的来源。
其中一些使用会让你直接进入"未定义行为领域",在那里你的编译器可以对你的代码做可怕的事情。
有些只是并不是真的那么随机。
如果您想要随机数,请使用<random>,并且如果您不直接使用random_device
(对于非加密安全数字,您可能不希望这样做),请确保您正确地为生成器播种。
甚至不要考虑rand()
——忘记它的存在。太可怕了。
您应该使用std::seed_seq
来混合多个熵源,然后使用它来为生成器种子。假设还包括其他更高质量的源(尤其是std::random_device
),则将变量的地址作为seed_seq
的许多输入之一是可以的。
- 作为随机数本身的来源,这非常糟糕,因为对于一个严重的对手来说,这是非常可预测的。正如其他人所说,地址空间是有限的,满足
int
对齐要求的地址要少得多,除此之外,将程序加载到内存中的算法(如果没有文档记录)至少不是为太多随机性而构建的 - 作为熵的来源,它取决于操作系统。如果操作系统不随机化,就会损害可读性——因为读代码的人可能会错误地认为你在添加熵。如果操作系统真的随机化了,它仍然不会是一个很好的熵源,你必须将它与其他更好的源结合起来进行补偿——这些源必须完全独立于随机地址的熵源
在任何情况下,这都是假设您使用变量的地址(完全有效),而不是其值。如果调用未定义的行为,操作可能会丢弃所有的熵。
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 整数不会重复超过随机数
- 算法问题:查找从堆栈中弹出的所有序列
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- if数组上的随机数
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 为什么调用堆栈数组会导致内存泄漏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 半随机数生成C++
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 堆栈和队列是否像C++中的数组一样传递?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 有没有办法在 c++ 中同时生成随机数?如果没有,是否有解决方法?
- 具有随机数的二维数组不会更改
- 随机数未达到限制
- 是堆栈指针,是伪随机数的良好来源