首頁 >後端開發 >C++ >如何穩健地播種 mt19937 PRNG 以實現更好的隨機數產生?

如何穩健地播種 mt19937 PRNG 以實現更好的隨機數產生?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-02 12:05:18503瀏覽

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

如何穩健地播種mt19937 PRNG

雖然通常建議使用std::random_device 播種者mt19937 PRNG 有許多缺點,包括熵不足的不均勻性。本文提出了一個克服這些問題的解決方案:

便攜式和徹底的播種

以下方法利用特定於平台的加密強度隨機字節來源(sysrandom)播種PRNG:

std::uint_least32_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937 gen(seed);

sysrandom是一個包裝函數,用於從適當的來源,取決於平台:

Windows:

  • CryptGenRandom(提供者: PROV_RSA_FULL)

類Unix:

  • /dev/urandom (後備:std::random_device若不可用)

其他:

  • std::random_device(建造議盡可能避免)

透過依賴在加密品質來源上,該解決方案確保足夠的熵和徹底的

與Boost 的比較

Boost 的 random_device 採用類似的技術(例如,Windows 上的 MS_DEF_PROV,*Nix 上的 /dev/urandom),使得所提出的方法在可移植性和品質。

Linux專業化

為了在 Linux 3.17 上增加安全性,可以使用 getrandom (如果 CSPRNG 未初始化則阻塞)代替/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警告

現代 OpenBSD 缺乏/dev/urandom。使用 getentropy 取代:

#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

以上是如何穩健地播種 mt19937 PRNG 以實現更好的隨機數產生?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn