ホームページ >バックエンド開発 >C++ >より良い乱数生成のために mt19937 PRNG を確実にシードする方法は?

より良い乱数生成のために mt19937 PRNG を確実にシードする方法は?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-02 12:05:18587ブラウズ

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 if利用不可)

その他:

  • std::random_device (可能であれば避けることをお勧めします)

依存することにより暗号品質のソースでは、このソリューションは十分なエントロピーと徹底した暗号化を保証します。

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。