首页 >后端开发 >C++ >如何稳健地播种 mt19937 PRNG 以实现更好的随机数生成?

如何稳健地播种 mt19937 PRNG 以实现更好的随机数生成?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-02 12:05:18502浏览

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