C での PRNG シーディングの問題への対処
std::random_device と time(NULL) への唯一の依存を避ける
std::random_device を使用するか、 time(NULL) だけでは、エントロピーが低く分布が不均一であるため、mt19937 をシードするには不十分です。
解決策: CSPRNG ラッパーを使用する
size_t sysrandom(void* dst, size_t dstlen);
最小限の解決策は、次のとおりです。以下に定義する sysrandom など、CSPRNG のラッパー。このラッパーは、暗号グレードのランダム バイトへのアクセスを提供します:
プラットフォーム固有の実装
size_t sysrandom(void* dst, size_t dstlen) { HCRYPTPROV ctx; ... // Acquire and release cryptographic context CryptGenRandom(ctx, dstlen, dst); return dstlen; }
Windows の場合、CryptGenRandom を利用できます:
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; }
Unix のようなシステムでは、次のものを使用できます。 /dev/urandom:
mt19937 のシード
std::uint_least32_t seed; sysrandom(&seed, sizeof(seed)); std::mt19937 gen(seed);
sysrandom ラッパーを使用すると、十分なビットで mt19937 をシードできます:
との比較Boost
このアプローチは、さまざまなプラットフォームで安全な CSPRNG を利用する boost::random_device と類似しています。
追加の考慮事項
Linux では、getrandom /dev/urandom のより安全な代替手段を提供します。 OpenBSD には /dev/urandom がありません。代わりに、getentropy を使用してください。
結論
この記事は、mt19937 PRNG を効果的にシードし、C で高品質な乱数生成を保証するための包括的なガイドを提供します以上が高品質の乱数生成のために C で mt19937 を確実にシードするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。