Votre générateur de nombres aléatoires est-il équitable ? Liste de contrôle pratique d’audit

Lorsque vous organisez un tirage au sort, choisissez des équipes au hasard ou attribuez des tâches par loterie, l'équité n'est pas facultative : c'est tout l'intérêt. Mais « aléatoire » ne signifie pas automatiquement « équitable ». Les biais cachés dans les générateurs de nombres aléatoires (RNG) peuvent fausser les résultats de manière invisible, à moins que vous ne sachiez où chercher.
Cet article vous donne une liste de contrôle pratique pour vérifier l'équité de tout RNG, que vous utilisiez notre Générateur de nombres aléatoires ou que vous construisiez le vôtre.
Ce que signifie l'équité pour les tirages face aux utilisateurs
Un RNG équitable produit des résultats où :
- Uniformity — chaque résultat a une probabilité égale (pour des distributions uniformes)
- Indépendance — chaque tirage n'est pas affecté par les tirages précédents
- Imprévisibilité — aucun observateur ne peut prédire le prochain résultat mieux que le hasard
- Vérifiabilité — les participants peuvent confirmer que le processus n'a pas été manipulé
Manquer l'un de ces éléments rompt la confiance, même si les résultats « semblent » aléatoires.
Sources courantes de biais
Mauvaises graines
A PRNG (générateur de nombres pseudo-aléatoires) est aussi imprévisible que sa graine. Mauvaises graines courantes :
- Horodatage actuel — prévisible à la milliseconde près ; un attaquant qui sait à peu près quand le tirage au sort aura lieu peut reproduire le résultat
- Compteurs séquentiels — pas aléatoires du tout
- Entrée utilisateur — peut être manipulé par les participants
Toujours générer à partir d'une source cryptographique : crypto.getRandomValues() dans les navigateurs, /dev/urandom sous Linux ou crypto.randomBytes() dans Node.js.
Biais modulo
Un bug subtil et courant : utiliser l'opérateur modulo pour réduire un nombre aléatoire à une plage.
// BIASED — si la plage RNG n'est pas un multiple de 6,
// certains résultats sont légèrement plus probables
const roll = randomUint32() % 6; // CORRECT — échantillonnage de rejet
fonction fairDiceRoll() { const max = Math.floor(0xFFFFFFFF / 6) * 6; laisser la valeur ; faire { value = crypto.getRandomValues(new Uint32Array(1))[0]; } while (valeur >= max) ; valeur de retour % 6 ;
}Pour un dé à 6 faces, le biais modulo avec un entier de 32 bits n'est que d'environ 0,00000009 %. Mais pour des plages plus grandes ou des valeurs de 8 bits, cela devient significatif.
Filtres cachés
Certains systèmes de tirage excluent silencieusement certains résultats (par exemple, en filtrant les « gagnants récents » ou en relançant les résultats que l'opérateur n'aime pas). Cela viole l'équité même si le RNG sous-jacent est parfait. Documentez et divulguez toutes les règles de filtrage avant le tirage au sort.
Liste de contrôle d'audit pour les opérateurs
Modèle de transparence pour les tombolas publiques
Pour les tirages à enjeux élevés (prix, missions, sélections), utilisez un système commit-reveal :
- Avant le tirage : Générez une graine aléatoire. Publier son hachage SHA-256 (l'« engagement »), par exemple sur les réseaux sociaux ou dans un document horodaté
- Exécutez le tirage : Utilisez la graine pour générer des résultats avec un algorithme déterministe
- Après le tirage au sort : Publier la graine. Tout le monde peut vérifier que :
- La graine produit le hachage publié
- L'algorithme seed + produit les résultats annoncés
Utilisez notre Hash Generator pour créer et vérifier le hachage d'engagement.
// Phase d'engagement
const seed = crypto.randomBytes(32).toString('hex');
engagement const = sha256(seed); // publie ceci avant le tirage au sort // Phase de dessin
résultat const = deterministicDraw (graine, participants); // Phase de révélation
// publier la graine — n'importe qui peut vérifier sha256(seed) === engagementCommuniquer l'équité avec les utilisateurs
La confiance nécessite de la transparence. Lors de l'exécution de tirages publics :
- Indiquez la méthode RNG utilisée (par exemple, "Web Crypto API")
- Publier l'algorithme de dessin (même le pseudocode aide)
- Utilisez commit-reveal pour la vérifiabilité
- Enregistrez et publiez les journaux de tirage avec horodatage
- Autoriser les observateurs indépendants à vérifier les résultats
FAQ
Math.random est-il suffisant ?
Non. Math.random() utilise un générateur de nombres pseudo-aléatoires (PRNG) qui n'est pas cryptographiquement sécurisé. Sa sortie peut être prédite si l'état interne est connu. Pour des tirages équitables, utilisez crypto.getRandomValues() dans le navigateur ou crypto.randomInt() dans Node.js.
Comment puis-je prouver qu'un tirage n'a pas été manipulé ?
Utilisez un schéma de validation-révélation : avant le tirage au sort, publiez un hachage de la graine aléatoire (engagement). Après le tirage, révélez la graine. N'importe qui peut vérifier que la graine produit le hachage publié et les résultats annoncés.
De combien d'échantillons ai-je besoin pour les contrôles de base des biais ?
Pour une simple vérification d'uniformité sur N résultats, vous avez besoin d'au moins 100 × N échantillons (par exemple, 1 000 échantillons pour un tirage à 10 options). Appliquez un test du Chi carré : si la valeur de p est supérieure à 0,05, la distribution est raisonnablement uniforme. Pour des audits sérieux, utilisez plus de 10 000 échantillons.
Outils et articles connexes
- Générateur de nombres aléatoires — nombres aléatoires cryptographiquement équitables
- Hash Generator — créez des hachages d'engagement pour des tirages vérifiables
- Pourquoi utiliser un générateur de code PIN ? – sécuriser des codes PIN aléatoires
- Liste de contrôle en matière d'hygiène numérique — pratiques de sécurité globales