According to this post, intuitive seeding with std::random_device
may not produce the expected results. In particular, if the Mersenne Twister engine is used, not all the initialization states can be reached. Using seed_seq doesn't helper either, since it is not a bijection.
This all, as far as I understand, means that not the std::uniform_int_distribution
will not really be uniform - because not all seed values are possible.
I'd like to simply generate a couple of random numbers. While this is a really interesting topic which I will certainly devote some of my free time, many people may not have this possibility.
So the question is: how should I properly seed the std::default_random_engine
so that it simply does what I expect?
A uniform_int_distribution
will still be uniform however you seed it. But better seeding can reduce chances of getting the same sequence of uniformly distributed values.
I think for most purposes using a std::seed_seq
with about 8 random 32bit ints from std::random_device
should be sufficient. It is not perfect, for the reasons given in the post you linked but if you need really secure numbers for cryptographic purposes you shouldn't really be using a pseudo random number generator anyway:
constexpr std::size_t SEED_LENGTH = 8;
std::array<uint_fast32_t, SEED_LENGTH> generateSeedData() {
std::array<uint_fast32_t, SEED_LENGTH> random_data;
std::random_device random_source;
std::generate(random_data.begin(), random_data.end(), std::ref(random_source));
return random_data;
}
std::mt19937 createEngine() {
auto random_data = generateSeedData();
std::seed_seq seed_seq(random_data.begin(), random_data.end());
return std::mt19937{ seed_seq };
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With