La réponse courte
Un ordinateur suit des instructions à la lettre : il ne peut donc pas inventer du hasard à partir de rien. Soit il calcule des nombres qui réussissent les tests statistiques de hasard (un générateur pseudo-aléatoire, ou PRNG), soit il mesure un phénomène physique imprévisible et le traite (une source vraiment aléatoire, ou matérielle). Les systèmes modernes combinent les deux : le système d'exploitation rassemble du bruit imprévisible et s'en sert pour initialiser un générateur pseudo-aléatoire cryptographiquement sûr (CSPRNG), qui produit ensuite autant de nombres que nécessaire.
Le générateur de cette page utilise la source sûre du navigateur via l'API Web Crypto et la ramène à votre intervalle sans biais. Saisissez un Minimum et un Maximum, choisissez Combien, puis appuyez sur Générer.
Essayez ici : Générateur de nombres aléatoires
Ouvrir la page complète de l'outilGénérateurs pseudo-aléatoires et graines
Un PRNG garde un état interne. Chaque fois que vous demandez un nombre, il brasse cet état avec une formule fixe et renvoie une partie du résultat. La conception classique la plus simple, le générateur congruentiel linéaire, calcule l'état suivant comme (a fois l'état plus c) modulo m. Des conceptions plus abouties, comme le Mersenne Twister (utilisé par défaut dans le module random de Python) ou la famille xorshift, produisent des suites de bien meilleure qualité, et le Mersenne Twister ne se répète qu'au bout de 2 puissance 19 937 moins 1 étapes.
La graine est l'état de départ. La même graine produit toujours la même suite. Dans bien des cas, c'est une qualité et non un défaut : un chercheur peut relancer une simulation à l'identique, un jeu peut reconstruire un monde à partir d'un court code de graine, et un test peut reproduire un bug. Mais si un programme prend comme graine une valeur facile à deviner, comme l'heure actuelle en secondes, un attaquant peut essayer toutes les graines probables et recréer les nombres.
Pseudo-aléatoire ou cryptographiquement sûr
Les PRNG rapides et polyvalents sont bons sur le plan statistique mais prévisibles : après avoir observé assez de résultats, on peut reconstituer leur état interne et prédire tous les nombres suivants. C'est sans importance pour un effet de particules dans un jeu, mais inacceptable pour un mot de passe, une loterie ou un jeton de sécurité.
| Type | Origine des nombres | Prévisible ? | Usage typique |
|---|---|---|---|
| PRNG simple (LCG, xorshift, Mersenne Twister) | Une formule et une graine | Oui, à partir de la graine ou d'assez de résultats | Simulations, jeux, graphisme |
| CSPRNG | Une formule initialisée et régulièrement réalimentée par le bruit du système | Non, pas en pratique | Mots de passe, clés, tirages au sort, jetons |
| Générateur matériel | Bruit physique, comme le bruit thermique ou les fluctuations de synchronisation | Non | Alimenter la réserve du système d'exploitation |
Où les ordinateurs trouvent du vrai hasard
Les systèmes d'exploitation collectent de petits événements imprévisibles : le moment exact des interruptions, l'activité du disque et du réseau, et les générateurs matériels intégrés à beaucoup de processeurs récents, qui échantillonnent du bruit électrique. Cette entropie est mélangée dans une réserve et sert à initialiser puis à réalimenter régulièrement un CSPRNG. Linux la rend accessible avec getrandom et /dev/urandom, Windows avec ses fonctions de cryptographie système.
Certains services vont plus loin, pour se faire connaître ou pour une garantie supplémentaire. Random.org utilise le bruit radio atmosphérique, et Cloudflare filme un mur de lampes à lave, devenu célèbre, comme l'une de ses sources d'entropie. Pour les besoins courants, le générateur du système d'exploitation est déjà assez solide pour des clés de chiffrement.
Comment les navigateurs créent des nombres aléatoires sûrs
JavaScript propose deux options. Math.random() renvoie un nombre entre 0 et 1 issu d'un PRNG rapide (les moteurs actuels utilisent des algorithmes de type xorshift). Il convient aux animations, mais il n'est pas conçu pour être imprévisible, et la spécification ne promet aucune sécurité.
crypto.getRandomValues() remplit un tableau d'octets aléatoires provenant du CSPRNG du navigateur, lui-même initialisé par le système d'exploitation. Cette fonction existe dans tous les navigateurs modernes, fonctionne hors connexion et c'est elle que doivent utiliser les générateurs de mots de passe et le code qui crée des clés. Un seul appel renvoie au maximum 65 536 octets, donc les gros travaux l'appellent plusieurs fois. Ce générateur, comme le pile ou face, le lancer de dés, la roue et le tirage de noms d'Anyfeat, utilise crypto.getRandomValues.
Pourquoi rand() % n peut être biaisé
Un générateur vous donne des valeurs brutes dans un intervalle fixe, par exemple un octet de 0 à 255. La façon évidente d'obtenir un nombre de 0 à 5 est de prendre le reste de la division par 6 (valeur % 6). Le problème : 256 valeurs ne se répartissent pas en 6 groupes égaux. 256 vaut 42 fois 6 plus 4, donc les restes 0 à 3 sortent 43 fois chacun et les restes 4 et 5 seulement 42 fois. Certains résultats sont environ 2,4 % plus probables que d'autres. C'est ce qu'on appelle le biais du modulo.
Avec des valeurs de 32 bits et un petit intervalle, le biais devient minuscule, mais il augmente avec les grands intervalles. La correction classique est l'échantillonnage par rejet : on prend le plus grand multiple de n qui tient dans l'intervalle brut (252 dans l'exemple de l'octet), on rejette toute valeur brute égale ou supérieure et on tire de nouveau. Toutes les valeurs restantes se répartissent alors également sur l'intervalle. Ce générateur tire des valeurs de 32 bits et rejette la queue inégale, si bien que chaque nombre de votre intervalle a exactement la même probabilité.
Une erreur voisine consiste à utiliser Math.floor(Math.random() * n) pour un usage de sécurité. L'arrondi convient pour la plupart des intervalles, mais la source est prévisible : il ne faut pas s'en servir pour des mots de passe ni pour des tirages où de l'argent est en jeu.
Nombres uniques, mélanges et pièges fréquents
- Nombres uniques : pour tirer sans répétition, mélangez tout l'intervalle avec l'algorithme de Fisher-Yates et prenez les k premiers, ou tirez et écartez les doublons. Ce générateur fait exactement cela quand Sans répétition est coché, et vous prévient si l'intervalle est trop petit pour la quantité demandée.
- Mélanges biaisés : trier une liste avec une fonction de comparaison aléatoire ne donne pas un mélange uniforme. Utilisez Fisher-Yates.
- Réinitialiser trop souvent : initialiser un PRNG avec l'heure dans une boucle peut produire le même nombre plusieurs fois de suite.
- Décimales : tirer une décimale en mettant à l'échelle une fraction aléatoire peut rendre les extrémités moins probables. Cet outil tire plutôt un nombre entier de pas (pour 2 décimales, des centièmes), de sorte que les deux extrémités sont incluses avec la même probabilité.
- Croire que le hasard n'a pas de motifs : un vrai tirage aléatoire contient des séries et des répétitions. Voir sortir 7 deux fois de suite ne signifie pas que le générateur est défaillant.