Home >Backend Development >C++ >How to Robustly Seed the mt19937 PRNG for Better Random Number Generation?

How to Robustly Seed the mt19937 PRNG for Better Random Number Generation?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-02 12:05:18509browse

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:

  • CryptGenRandom (provder: PROV_RSA_FULL)

Unix-Like:

  • /dev/urandom (fallback: std::random_device if unavailable)

Other:

  • std::random_device (recommended to avoid if possible)

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn