Maison > développement back-end > C++ > Comment amorcer de manière robuste le PRNG mt19937 pour une meilleure génération de nombres aléatoires ?

Comment amorcer de manière robuste le PRNG mt19937 pour une meilleure génération de nombres aléatoires ?

Mary-Kate Olsen
Libérer: 2024-12-02 12:05:18
original
510 Les gens l'ont consulté

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

Comment amorcer le PRNG mt19937 de manière robuste

Bien que cela soit généralement suggéré, l'utilisation de std::random_device pour amorcer un PRNG mt19937 présente de nombreuses lacunes, notamment entropie insuffisante et non-uniformité potentielle. Cet article présente une solution qui résout ces problèmes :

Amorçage portable et approfondi

L'approche suivante utilise une source spécifique à la plate-forme d'octets aléatoires de force cryptographique (sysrandom) pour amorcer le PRNG :

std::uint_least32_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937 gen(seed);
Copier après la connexion

sysrandom est une fonction wrapper qui récupère des octets aléatoires à partir d'une source appropriée, en fonction sur la plateforme :

Windows :

  • CryptGenRandom (fournisseur : PROV_RSA_FULL)

Unix-Like :

  • /dev/urandom (repli : std::random_device si indisponible)

Autre :

  • std::random_device (il est recommandé d'éviter si possible)

En s'appuyant sur des sources de qualité cryptographique, cette solution garantit une entropie suffisante et une seeding.

Comparaison avec Boost

Le random_device de Boost utilise des techniques similaires (par exemple, MS_DEF_PROV sur Windows, /dev/urandom sur *Nix), rendant l'approche présentée comparable dans portabilité et qualité.

Linux Spécialisation

Pour plus de sécurité sous Linux 3.17, getrandom (qui bloque si CSPRNG n'est pas initialisé) peut être utilisé à la place de /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
Copier après la connexion

OpenBSD Attention

OpenBSD moderne ne dispose pas de /dev/urandom. Utilisez plutôt getentropy :

#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
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal