使用来自更好随机源的随机数播种伪随机生成器
Seeding pseudo random generator with random number from a better random source
假设我们有一个伪随机数生成器,它接受一个 32 位整数作为种子(例如 C 标准库中的 rand()
函数),它从原始种子中导出随机数。如果那个种子来自,比方说,放射性衰变,假设我们通过调用 rand()
获得的随机数与从放射性衰变中生成随机数一样 "good" 是正确的吗?
随机数的质量取决于随机数生成器的质量。生成伪随机数的方法多种多样,您应该选择适合您应用的方法,但老实说,如果您有放射性衰变监测设备,那么您很可能能够获得真正的随机数(来自其他一些完全随机的现实世界事件),而不是播种伪事件。
不,绝对不是。 C/C++ 标准库的内置 rand()
函数通常实现为 linear congruential generator (LCG). It is among the earliest known family of pseudorandom number generators (PRNGs) and they generally have notoriously bad statistical properties. Furthermore since PRNGs actually produce a mathematical sequence predetermined by an initial seed, they are predictable. Even cryptographically secure pseudorandom number generators (like the Blum Blum Shub) 是可预测的,即使预测序列在计算上很困难且非常耗时。
相比之下,基于放射性衰变的随机数发生器才是真正的随机数发生器。生成的数字序列完全均匀分布且不可预测,样本之间没有任何可测量的相关性。
回到伪随机数,初始种子源的统计质量不会提高生成的伪随机序列的统计质量——它只取决于生成器本身。如果您使用真正的随机数作为 PRNG 的种子,那么序列的第一个数字将不可预测,但随后序列的质量将与没有真正随机种子的情况相同。
如果你想要高质量的随机数,你必须使用高质量的随机数生成器。有一些伪随机数生成器具有出色的统计特性(绝对 而不是 著名的 Mersenne Twister),通过了所有当前的随机性统计测试 - 虽然生成的伪随机序列仍然是可预测的,但从统计上来说它是很难与真正的随机序列区分开来。
关于现代随机数生成器的一个很好的可靠资源是 Sebastiano Vigna's website。
否。随机数sequence的属性完全取决于随机数生成器(RNG)。因此,后续随机数之间的任何相关性都取决于 RNG 而不是种子。
然而,话虽如此,种子对于避免在不同代码运行时生成的序列之间存在相似性很重要。因此,您应该始终尝试使用真正随机的种子为您的 RNG 播种。
伪随机数 (PRN) 可能是一个 接近随机数 的序列。然而,真随机数 (TRN) 是通过从 熵源 获取输入来生成随机数的,它可以是从振动到硬盘的任何物理环境 activity . C库的rand()属于PRN的范畴。对于高随机性,最好使用使用 /dev/random 或 /dev/urandom.
的库
有关 random、urandom - 内核随机数源设备的更多详细信息,请参阅 urandom 的联机帮助页 https://linux.die.net/man/4/urandom。
" 随机数生成器将来自设备驱动程序和其他来源的环境噪声收集到一个熵池中。生成器还会对熵池中的噪声位数进行估计。从这个熵池中创建随机数."
假设我们有一个伪随机数生成器,它接受一个 32 位整数作为种子(例如 C 标准库中的 rand()
函数),它从原始种子中导出随机数。如果那个种子来自,比方说,放射性衰变,假设我们通过调用 rand()
获得的随机数与从放射性衰变中生成随机数一样 "good" 是正确的吗?
随机数的质量取决于随机数生成器的质量。生成伪随机数的方法多种多样,您应该选择适合您应用的方法,但老实说,如果您有放射性衰变监测设备,那么您很可能能够获得真正的随机数(来自其他一些完全随机的现实世界事件),而不是播种伪事件。
不,绝对不是。 C/C++ 标准库的内置 rand()
函数通常实现为 linear congruential generator (LCG). It is among the earliest known family of pseudorandom number generators (PRNGs) and they generally have notoriously bad statistical properties. Furthermore since PRNGs actually produce a mathematical sequence predetermined by an initial seed, they are predictable. Even cryptographically secure pseudorandom number generators (like the Blum Blum Shub) 是可预测的,即使预测序列在计算上很困难且非常耗时。
相比之下,基于放射性衰变的随机数发生器才是真正的随机数发生器。生成的数字序列完全均匀分布且不可预测,样本之间没有任何可测量的相关性。
回到伪随机数,初始种子源的统计质量不会提高生成的伪随机序列的统计质量——它只取决于生成器本身。如果您使用真正的随机数作为 PRNG 的种子,那么序列的第一个数字将不可预测,但随后序列的质量将与没有真正随机种子的情况相同。
如果你想要高质量的随机数,你必须使用高质量的随机数生成器。有一些伪随机数生成器具有出色的统计特性(绝对 而不是 著名的 Mersenne Twister),通过了所有当前的随机性统计测试 - 虽然生成的伪随机序列仍然是可预测的,但从统计上来说它是很难与真正的随机序列区分开来。
关于现代随机数生成器的一个很好的可靠资源是 Sebastiano Vigna's website。
否。随机数sequence的属性完全取决于随机数生成器(RNG)。因此,后续随机数之间的任何相关性都取决于 RNG 而不是种子。
然而,话虽如此,种子对于避免在不同代码运行时生成的序列之间存在相似性很重要。因此,您应该始终尝试使用真正随机的种子为您的 RNG 播种。
伪随机数 (PRN) 可能是一个 接近随机数 的序列。然而,真随机数 (TRN) 是通过从 熵源 获取输入来生成随机数的,它可以是从振动到硬盘的任何物理环境 activity . C库的rand()属于PRN的范畴。对于高随机性,最好使用使用 /dev/random 或 /dev/urandom.
的库有关 random、urandom - 内核随机数源设备的更多详细信息,请参阅 urandom 的联机帮助页 https://linux.die.net/man/4/urandom。 " 随机数生成器将来自设备驱动程序和其他来源的环境噪声收集到一个熵池中。生成器还会对熵池中的噪声位数进行估计。从这个熵池中创建随机数."