使用来自更好的随机源的随机数播种伪随机生成器
Seeding pseudo random generator with random number from a better random source
假设我们有一个伪随机数生成器,它接受一个 32 位整数作为种子(例如 C 标准库中的rand()
函数),它从原始种子派生随机数。如果那颗种子来自放射性衰变,假设我们从调用rand()
中获得的随机数与从放射性衰变中产生一个随机数一样"好",这是否正确?
不,绝对不是。C/C++ 标准库的内置rand()
函数通常作为线性全余生成器 (LCG) 实现。它是已知最早的伪随机数生成器(PRNG)家族之一,它们通常具有臭名昭著的不良统计特性。此外,由于PRNG实际上产生由初始种子预先确定的数学序列,因此它们是可预测的。即使是加密安全的伪随机数生成器(如 Blum Blum Blum Shub)也是可预测的,即使预测序列在计算上很困难且非常耗时。
相反,基于放射性衰变的随机数生成器是真正的随机数生成器。生成的数字序列完全均匀分布且不可预测,样本之间没有任何可测量的相关性。
回到伪随机数,初始种子源的统计质量不会提高生成的伪随机序列的统计质量——它只取决于生成器本身。如果您使用真正的随机数为 PRNG 设定种子,那么序列的第一个数字将是不可预测的,但序列的质量将与没有真正的随机种子的质量相同。
如果你想要高质量的随机性,你必须使用高质量的随机数生成器。有一些伪随机数生成器具有出色的统计特性(绝对不是著名的 Mersenne Twister),通过了当前所有随机性的统计测试 - 虽然生成的伪随机序列仍然是可预测的,但从统计学上很难与真正的随机序列区分开来。
关于现代随机数生成器的一个很好的可靠资源是Sebastiano Vigna的网站。
随机数的质量来自随机数生成器的质量。 生成伪随机数的方法多种多样,您选择的方法应该适合您的应用,但说实话,如果您可以使用无线电主动衰减监测设备,那么您可能能够访问真实随机数(来自其他一些完全随机的现实世界事件),而不是播种伪随机数。
NO.随机数序列的属性完全取决于随机数生成器 (RNG)。因此,后续随机数之间的任何相关性都取决于RNG,而不是种子。
但是,话虽如此,种子对于避免在不同代码运行中生成的序列之间的相似性非常重要。因此,您应该始终尝试使用真正随机的种子为您的 RNG 播种。
伪随机数 (PRN) 可以是近随机数的序列。但是,真随机数 (TRN) 是通过从熵源获取输入来生成随机数的随机数,熵源可以是任何类型的物理环境,从振动到硬盘活动。C 库的 rand() 属于 PRN 的范畴。对于高随机性,最好使用使用/dev/random 或/dev/urandom 的库。
有关随机、urandom - 内核随机数源设备的更多详细信息,请参阅 urandom 的手册页,请参见 https://linux.die.net/man/4/urandom。" 随机数生成器将来自设备驱动程序和其他来源的环境噪声收集到熵池中。生成器还保留熵池中噪声位数的估计值。从这个熵池中创建随机数。">
- C++:将控制台输出存储在宏中更好吗
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 为什么新的随机库比std::rand()更好
- 寻找一种更好的方法来表示无符号字符数组
- 哪种方法更好,性能明智
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 什么是更好的做法?通过指针或标识符传递类成员?
- 寻求更好地理解标准::访问
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 有没有更好的方法来处理异常? try-catch块真的很丑
- 如何更好地检查两个 char 变量是否在一组值中?
- 有没有更好的方法对C++中的三个整数进行排序?
- 什么模板用法在阶乘中更好
- 平面缓冲区可以利用向量中的 0 吗?还是其他小波比哈尔变换更好?
- 我们应该如何使用枚举类进行索引(或者我们应该更好地避免这种情况)?
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- 使用来自更好的随机源的随机数播种伪随机生成器
- 有没有比这更好的方法从可变大小的数组中选择随机元素