解决 C 语言中的 PRNG 播种问题
尽管广泛使用了
避免单独依赖 std::random_device 和 time(NULL)
单独使用 std::random_device 或 time(NULL) 不足以进行播种mt19937 由于低熵和不均匀分布。
解决方案:使用 CSPRNG 包装器
最小的解决方案是在 CSPRNG 周围使用包装器,例如 sysrandom定义如下。此包装器提供对加密级随机字节的访问:
size_t sysrandom(void* dst, size_t dstlen);
特定于平台的实现
对于 Windows,我们可以利用 CryptGenRandom:
size_t sysrandom(void* dst, size_t dstlen) { HCRYPTPROV ctx; ... // Acquire and release cryptographic context CryptGenRandom(ctx, dstlen, dst); return dstlen; }
在类 Unix 系统上,我们可以使用/dev/urandom:
size_t sysrandom(void* dst, size_t dstlen) { std::ifstream stream("/dev/urandom", std::ios_base::binary | std::ios_base::in); stream.read(dst, dstlen); return dstlen; }
播种 mt19937
使用 sysrandom 包装器,我们可以为 mt19937 播种足够的位:
std::uint_least32_t seed; sysrandom(&seed, sizeof(seed)); std::mt19937 gen(seed);
比较Boost
此方法与 boost::random_device 类似,后者在各种平台上利用安全 CSPRNG。
其他注意事项
在 Linux 上,getrandom提供了 /dev/urandom 的更安全的替代方案。 OpenBSD 缺少 /dev/urandom;相反,使用 getentropy。
结论
本文提供了有效播种 mt19937 PRNG 的全面指南,确保在 C 中生成高质量的随机数
以上是如何在 C 中可靠地播种 mt19937 以生成高质量的随机数?的详细内容。更多信息请关注PHP中文网其他相关文章!