首页 > 解决方案 > 在 C++ 中生成随机数

问题描述

我的任务是在 C++ 中生成数万个随机数。我在 C++ 中搜索了很多关于随机数的信息并查找了 C++ 参考资料,但现在我很困惑。

据我所知,random_device 是一个非确定性的随机数生成器,但是每次我重新运行我的程序时,random_device 生成的随机数都是一样的。那么当我重新启动程序时,如何为 random_device 设置种子以使随机数不同?

而且我读过“如果您尝试从中获取大量数字,std::random_device 可能会耗尽熵。这可能会导致它阻塞,直到您移动鼠标或其他东西”。这意味着我的程序可能会在某个时间暂停。我怎样才能避免这种情况发生?

标签: c++randomrandom-seed

解决方案


这里,您可以看到std::random_device并不总是保证是非确定性的:

如果非确定性源(例如硬件设备)对实现不可用,则std::random_device 可以根据实现定义的伪随机数引擎来实现。在这种情况下,每个 std::random_device 对象都可以生成相同的数字序列

在 Linux 上,它默认使用/dev/urandomRDRNDCPU 指令根据这里

libc++ 和 libstdc++ 中的实现期望 token 是读取时产生随机数的字符设备的名称,默认值为 "/dev/urandom",尽管在 CPU 指令 RDRND 可用的情况下,libstdc++ 使用它作为默认值.

不会阻止/dev/random您可以使用此处的方法切换到更安全的设备,但如果没有足够的熵,该设备将阻塞。

在 Windows 上,我不确定这样的设备,因此它可能会退回到一些需要某种种子的 PRNG。

要跨平台解决问题,正如@Binara 提到的,您可以使用std::randfrom <cstdlib>. 此功能不会阻塞,您可以使用std::srand(somethingLikeCurrentTime)它来使其具有某种不确定性。

正如@user1118321 提到的,如果您想使用更安全的 PRNG,您可以考虑std::mersenne_twister_engine并使用std::random_device它来生成它的种子。此处建议使用此方法。


推荐阅读