Un programme qui choisit un chiffre entre 1 et 100 ne ferme pas les yeux et ne lance pas des dés virtuels. Il exécute une fonction mathématique qui, à partir d’un point de départ, produit une séquence de valeurs statistiquement difficile à distinguer du hasard. Le mot important, c’est “statistiquement”. L’illusion est parfaite pour l’œil humain, mais derrière le rideau, chaque tirage successif est une conséquence mécanique du précédent.

C’est tout le problème, et toute la beauté, du sujet. On demande sans cesse à nos machines de générer des nombres aléatoires: pour un tirage au sort, pour initialiser une simulation météo, pour brouiller une communication. Et la machine, qui déteste ne pas avoir de réponse, applique la seule chose qu’elle sache faire: un calcul. Ce calcul, c’est ce qu’on appelle un générateur de nombres pseudo-aléatoires (PRNG, en anglais). Le “pseudo” est rarement écrit sur les boutons des applis, mais il est partout.

Cette ambiguïté entre le hasard vrai et le hasard calculé n’est pas un détail de chercheur. Elle définit ce que vous pouvez faire, ou ne pas faire, avec l’outil que vous utilisez.

La mécanique du “comme si”

Un générateur de nombres pseudo-aléatoires fonctionne toujours de la même façon. Il prend une donnée d’entrée unique, que les cryptologues et les développeurs appellent la graine (ou seed), et la passe dans une moulinette arithmétique. Le résultat est un nombre. Ce nombre est stocké pour servir de graine au prochain tirage. Si on rembobine le processus et qu’on repart de la même graine, on obtient la suite exacte de chiffres. C’est le contraire du chaos: un processus parfaitement reproductible.

La qualité d’un générateur tient donc à deux choses. La première est la qualité de sa fonction de brassage: l’algorithme qui va transformer la graine en un nombre à l’apparence imprévisible. Le Mersenne Twister, par exemple, est un algorithme bien connu pour sa longue période (le nombre de tirages avant que la séquence ne se répète) et sa bonne distribution statistique des valeurs. Il a longtemps été le standard dans les langages de programmation.

La graine: le faux hasard a un point de départ

Choisir la graine est un art en soi. Si un programme compétiteur initialise toujours sa routine de hasard avec le même chiffre, la séquence de nombres générés est identique d’une course à l’autre. Un joueur pourrait prédire la trajectoire d’un obstacle.

Les systèmes d’exploitation contournent ce problème en puisant dans une source d’entropie, un réservoir de chaos interne constitué de micro-événements imprévisibles: le temps exact entre deux frappes au clavier, le mouvement infime de la souris, le trafic réseau, le bruit thermique dans les circuits. Ce réservoir est utilisé pour forger une graine quasi-imprévisible, que l’utilisateur ne peut pas deviner.

Quand le matériel fabrique du chaos vrai

Il existe une autre catégorie, bien plus rare, qu’on appelle les générateurs matériels de nombres aléatoires (TRNG, True Random Number Generator). Ceux-là exploitent un phénomène physique quantique ou thermique fondamentalement imprévisible pour produire des bits. Un processeur moderne embarque souvent un module dédié, RDRAND chez Intel par exemple. On sort du domaine du calcul pur pour entrer dans celui de la mesure d’un bruit. Le débit est plus faible, impraticable pour générer des millions de nombres par seconde, mais la qualité du hasard est inégalée. C’est la seule façon d’obtenir un nombre “vraiment” aléatoire au sens strict. L’immense majorité des services en ligne que vous utilisez n’en font pas appel, car le pseudo-aléatoire est plus rapide et, pour l’usage visé, parfaitement indiscernable.

Le générateur que vous utilisez ment (et c’est tant mieux)

Les outils en ligne pour tirer un numéro au hasard sont légion. tirage-au-sort.net, tirokdo.com ou encore ladigitale.dev proposent des interfaces simples: vous définissez un minimum, un maximum, et vous obtenez un chiffre. Ils utilisent tous, sans exception, une variante de PRNG.

Ils sont trompeurs parce qu’ils donnent l’impression de réaliser un acte unique. Mais derrière le clic, ils se contentent d’appeler une fonction comme Math.random() du navigateur, qui elle-même utilise un algorithme comme xorshift128+, rapide et bien distribué sur l’intervalle demandé. Pour choisir qui va sortir les poubelles, ou pour déterminer un gagnant à un jeu-concours sans enjeu financier, cette tricherie est totalement indolore. Personne n’a besoin d’un dispositif à fission nucléaire pour décider qu’on mangera des pizzas plutôt que des sushis.

La même logique prévaut dans les jeux. Quand un jeu de rôle génère un butin dit “aléatoire”, il ne simule pas un lancer de dés dans un monde parallèle. Il exécute une table de probabilités pondérée, parcourue par un PRNG. Les amateurs de speedrun exploitent sans le dire des défauts dans ces générateurs pour manipuler l’apparition d’objets rares. Ils ne trichent pas avec la chance, ils trichent avec l’algorithme qui tient lieu de chance. C’est le même principe qui permet à un statisticien de reproduire une simulation complexe en partageant sa graine: le hasard apparent devient une science exacte et vérifiable.

Le seul endroit où ça ne suffit plus

Le débat change radicalement quand on parle de sécurité. Un mot de passe, une clé privée, un jeton de session. Si un attaquant peut deviner ou reproduire la graine du générateur qui a servi à les produire, il peut casser le système en régénérant la même séquence. L’affaire du bug Debian OpenSSL en 2008 en est l’illustration parfaite: une modification malheureuse du code a supprimé la seule source d’entropie réelle, réduisant toutes les clés générées à une poignée de possibilités. Le hasard était faux, prévisible, et la catastrophe prévisible également.

Une bonne bibliothèque cryptographique ne se contente pas de brasser des bits. Elle puise en continu dans le réservoir d’entropie du système, qu’elle mélange à des algorithmes de hachage pour produire des nombres imprévisibles même si une partie de l’état interne venait à fuiter. La fonction utilisée ne sera pas Math.random() mais un CSPRNG (Cryptographically Secure Pseudo-Random Number Generator), conçu pour résister à des attaques de prédiction de l’état suivant ou précédent.

Cette distinction a été au cœur du succès des wallets matériels. Leur argument n’est pas leur robustesse physique, mais le fait qu’ils génèrent des graines de récupération de portefeuilles crypto avec un TRNG intégré plutôt qu’avec le PRNG d’un navigateur, par définition moins maîtrisable. C’est l’une des nombreuses zones où une application comme Abacus IA trouve son intérêt en local: vous ne confiez pas à un serveur lointain la génération d’une donnée dont dépend toute votre sécurité.

Comprendre le tirage avec et sans remise

L’autre notion pratique qui apparaît dès qu’on utilise un tel outil, c’est la remise. Un tirage avec remise considère que chaque nombre tiré est remis dans l’urne avant le prochain tirage. La probabilité de tirer le même chiffre au prochain essai est identique. C’est absurde si vous voulez attribuer des places dans un concours à 10 personnes sans en favoriser aucune, vous utiliseriez sans doute un tirage sans remise. Mais c’est utile dans une simulation où les événements sont indépendants: la probabilité de pluie demain ne dépend pas de ce qui s’est passé avant-hier.

Coder un tirage sans remise est un bon test. Un développeur paresseux demandera au générateur de tirer une liste de chiffres, et si un chiffre déjà tiré ressort, il relancera la fonction jusqu’à en obtenir un inédit. La probabilité de collision augmente à mesure que la liste se remplit. Le temps d’exécution devient alors aléatoire, parfois très long. La solution correcte, c’est l’algorithme de Fisher-Yates: on parcourt la liste, et à chaque indice, on échange la valeur courante avec un élément situé à une position aléatoire postérieure. On obtient en un seul passage un mélange parfaitement uniforme de tous les éléments, qu’on n’a plus qu’à dépiler pour obtenir un tirage sans remise optimal.

Questions fréquentes

Questions fréquentes

Est-ce qu’un ordinateur peut véritablement générer du hasard?

Non, pas par le calcul seul. Un ordinateur est une machine déterministe: une même entrée produit toujours une même sortie. Pour obtenir du hasard authentique, il doit mesurer un phénomène physique chaotique externe (bruit thermique, désintégration radioactive, variation de tension). On appelle cela un générateur matériel de nombres aléatoires (TRNG). Tout le reste, tout ce qui vient d’un logiciel pur, est pseudo-aléatoire: une imitation.

Pourquoi un générateur de nombres peut-il tomber en panne?

Un générateur logiciel tombe en panne quand sa source d’entropie s’épuise ou est mal initialisée. Sur des serveurs qui démarrent en masse avec une configuration identique ou des objets connectés sans activité clavier/souris, le réservoir de chaos peut être vide au moment de produire une clé. Les résultats sont alors reproductibles d’une machine à l’autre, ce qui est une faille de sécurité majeure.

Quelle est la différence entre Math.random() et les fonctions de crypto en programmation?

Math.random() est un PRNG optimisé pour la vitesse et une distribution statistique uniforme sur un intervalle donné. Il n’est pas conçu pour résister à une analyse qui tenterait de prédire la graine ou l’état interne. Les fonctions cryptographiques, comme crypto.getRandomValues(), sont des CSPRNG. Leur algorithme est conçu pour qu’il soit mathématiquement infaisable, en observant les nombres générés, de remonter à l’état interne ou de prédire le prochain tirage. C’est cette différence qui fait que l’un convient pour gérer votre budget et l’autre pour chiffrer vos données.

Quiz personnalisé

Votre recommandation sur numéro au hasard

Quelques questions rapides pour adapter la recommandation à votre cas.

Q1Votre situation sur numéro au hasard ?
Q2Votre priorité ?
Q3Votre horizon ?