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 のセキュリティを強化するには、/dev/urandom の代わりに getrandom (CSPRNG が初期化されていない場合にブロックします) を使用できます:
#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.代わりに取得トロピーを利用してください:
#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 中国語 Web サイトの他の関連記事を参照してください。