Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Menanam dengan Teguh PRNG mt19937 untuk Penjanaan Nombor Rawak yang Lebih Baik?

Bagaimana untuk Menanam dengan Teguh PRNG mt19937 untuk Penjanaan Nombor Rawak yang Lebih Baik?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-02 12:05:18503semak imbas

How to Robustly Seed the mt19937 PRNG for Better Random Number Generation?

Cara Menyemai PRNG mt19937 dengan Teguh

Walaupun biasa dicadangkan, menggunakan std::random_device untuk menyemai PRNG mt19937, termasuk banyak kelemahan entropi yang tidak mencukupi dan potensi ketidakseragaman. Artikel ini membentangkan penyelesaian yang mengatasi isu ini:

Pembenihan Mudah Alih dan Teliti

Pendekatan berikut menggunakan sumber khusus platform bagi bait rawak kekuatan kriptografi (sysrandom) untuk menyemai PRNG:

std::uint_least32_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937 gen(seed);

sysrandom ialah fungsi pembungkus yang mendapatkan bait rawak daripada sumber yang sesuai, bergantung pada platform:

Windows:

  • CryptGenRandom (penyedia: PROV_RSA_FULL)

Seperti Unix:

  • /dev/urandom (fallback: std::random_device jika tidak tersedia)

Lain-lain:

  • std::random_device (disyorkan untuk mengelakkan jika boleh)

Dengan bergantung pada sumber kualiti kriptografi, penyelesaian ini memastikan entropi yang mencukupi dan teliti pembenihan.

Perbandingan dengan Boost

Peranti rawak Boost menggunakan teknik yang serupa (cth., MS_DEF_PROV pada Windows, /dev/urandom pada *Nix), menjadikan pendekatan yang dibentangkan setanding dalam mudah alih dan kualiti.

Linux Pengkhususan

Untuk keselamatan tambahan pada Linux 3.17 , getrandom (yang menyekat jika CSPRNG tidak dimulakan) boleh digunakan dan bukannya /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 Kaveat

OpenBSD moden kekurangan /dev/urandom. Gunakan getentropy sebaliknya:

#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

Atas ialah kandungan terperinci Bagaimana untuk Menanam dengan Teguh PRNG mt19937 untuk Penjanaan Nombor Rawak yang Lebih Baik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn