我使用以下代码来测试c++ <random>
库。
为什么每次运行已编译的可执行文件时都会获得完全相同的序列?编译时rd()
是否确定?如何为每次运行获得不同的输出?
Windows 7 64位上的GCC 4.8.1。使用http://nuwen.net/mingw.html
中的MinGW分发编辑:我使用Visual Studio测试了相同的代码。没有问题。输出是不确定的。这可能是我使用的mingw gcc 4.8.1中的错误。
#include <iostream>
#include <random>
using namespace std;
int main(){
random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dist(0,99);
for (int i = 0; i< 16; ++i){
cout<<dist(mt)<<" ";
}
cout <<endl;
}
答案 0 :(得分:31)
来自http://en.cppreference.com/w/cpp/numeric/random/random_device:
注意,如果非确定性源(例如硬件设备)不可用于实现,则std :: random_device可以用伪随机数引擎实现。
我希望有一个不错的实现,至少可以为RNG播种。
编辑:我怀疑他们每次都故意选择提供相同的序列,以明确说明流不像承诺的那样随机。
答案 1 :(得分:24)
我从STL from MSFT得到了确认答案:
与VC不同,GCC尚未在Windows上实现不确定的random_device。 Boost有,所以你可以使用Boost.Random。
答案 2 :(得分:3)
您可能需要将参数传递给构造函数:
https://gcc.gnu.org/onlinedocs/gcc-4.9.1/libstdc++/api/a00899.html
答案 3 :(得分:3)
这是GCC bug,已在GCC 9.2中修复。
如果遇到此问题,请更新编译器。 (例如,您可以从MSYS2获得新的GCC。)
答案 4 :(得分:2)
GCC没有正确实现rd.entropy() - 它总是返回0(至少在Mac OS X上)。
不幸的是,似乎没有办法将额外的熵混合到random_device中,这很重要,因为它通常/经常(查看Linux / dev / random和/ dev / urandom,并在Intel RDRAND实现中)实现引擎盖下的伪随机数发生器。我希望能够通过注入我认为随机混合的东西来改善其输出,无论其熵源产生什么。同样,由于此设备(或内核模块)在内部实现加密算法以处理它获得的熵位以生成其输出,我希望能够随机化&#34 34;通过注入我自己的数据以与设备选择的任何熵混合来进行更多处理。 例如,考虑Java SecureRandom()。它不允许你设置种子(确实会将它转换为PRNG),但是它会很乐意将你提供的内容与它所使用的内容混合在一起来随机化&#34;随机化&#34;它的输出更多。
我个人更喜欢RDRAND。具有紧凑C接口的小型装配库。以下是参考资料:
David Johnson from Intel explains RDRAND on Stackoverflow
Stackoverflow pointers to RDRAND library source for Windows, Linux, and Mac OS X