如何稳健地播种 mt19937 PRNG
虽然通常建议使用 std::random_device 播种 mt19937 PRNG 有许多缺点,包括熵不足和潜在的不均匀性。本文提出了一个克服这些问题的解决方案:
便携式和彻底的播种
以下方法利用特定于平台的加密强度随机字节源 (sysrandom)播种 PRNG:
std::uint_least32_t seed; sysrandom(&seed, sizeof(seed)); std::mt19937 gen(seed);
sysrandom 是一个包装函数,用于从合适的来源,取决于平台:
Windows:
类 Unix:
其他:
通过依赖在加密质量源上,该解决方案确保足够的熵和彻底的
与 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中文网其他相关文章!