Home >Backend Development >C++ >How to Robustly Seed the mt19937 PRNG for Better Random Number Generation?
How to Seed the mt19937 PRNG Robustly
While commonly suggested, using std::random_device to seed an mt19937 PRNG has numerous shortcomings, including insufficient entropy and potential non-uniformity. This article presents a solution that overcomes these issues:
Portable and Thorough Seeding
The following approach utilizes a platform-specific source of cryptographic-strength random bytes (sysrandom) to seed the PRNG:
std::uint_least32_t seed; sysrandom(&seed, sizeof(seed)); std::mt19937 gen(seed);
sysrandom is a wrapper function that retrieves random bytes from a suitable source, depending on the platform:
Windows:
Unix-Like:
Other:
By relying on cryptographic-quality sources, this solution ensures sufficient entropy and thorough seeding.
Comparison to Boost
Boost's random_device employs similar techniques (e.g., MS_DEF_PROV on Windows, /dev/urandom on *Nix), making the presented approach comparable in portability and quality.
Linux Specialization
For added security on Linux 3.17 , getrandom (which blocks if CSPRNG is not initialized) can be used instead of /dev/urandom:
#if defined(__linux__)... size_t sysrandom(void* dst, size_t dstlen) { int bytes = syscall(SYS_getrandom, dst, dstlen, 0); if (bytes != dstlen) { throw std::runtime_error(...); } return dstlen; } #elif defined(_WIN32)... #else... #endif
OpenBSD Caveat
Modern OpenBSD lacks /dev/urandom. Utilize getentropy instead:
#if defined(__OpenBSD__)... size_t sysrandom(void* dst, size_t dstlen) { int bytes = getentropy(dst, dstlen); if (bytes != dstlen) { throw std::runtime_error(...); } return dstlen; } #endif
The above is the detailed content of How to Robustly Seed the mt19937 PRNG for Better Random Number Generation?. For more information, please follow other related articles on the PHP Chinese website!