To fill you in: Many people seed their Mersenne Twister engines like this:
std::mt19937 rng(std::random_device{}());
However, this only provides a single unsigned int
, i.e. 32 bits on most systems, of seed randomness, which seems quite tiny when compared to the 19937 bit state space we want to seed. Indeed, if I find out the first number generated, my PC (Intel i7-4790K) only needs about 10 minutes to search through all 32 bit numbers and find the used seed. (I know that MT is not a cryptographic RNG, but I just did that to get a feel for how small 32 bit really is in these days.)
So I am trying to build a function to properly seed a mt19937
. This is what I and came up with this:
#include <algorithm>
#include <iostream>
#include <random>
auto RandomlySeededMersenneTwister () {
// Magic number 624: The number of unsigned ints the MT uses as state
std::vector<unsigned int> random_data(624);
std::random_device source;
std::generate(begin(random_data), end(random_data), [&](){return source();});
std::seed_seq seeds(begin(random_data), end(random_data));
std::mt19937 seededEngine (seeds);
return seededEngine;
}
int main() {
auto rng = RandomlySeededMersenneTwister();
for (int i = 0; i < 10; ++i)
std::cout << rng() << "\n";
}
This does look like a safe solution to me; however, I have learned that problems with RNG are often times quite subtle.
So the question is: Provided std::random_device
produces good, random data on my system, does the above code give me a correctly seeded std::mt19937
?