Français

Outils de développement · Générateur UUID

Combien de bits aléatoires une version 4 UUID possède-t-elle ? 122, pas 128

· Comment ça marche

uuid cryptographie API du navigateur

Un champ 128 bits avec 6 bits fixes (version et variante) en surbrillance et 122 bits aléatoires affichés, illustrant pourquoi la probabilité de collision est calculée à partir de 122 bits
Illustration vectorielle originale de ToolAcre

Six des 128 bits dans un UUID aléatoire sont fixés par la norme, laissant 122 pour le caractère aléatoire. Cet article montre comment estimer honnêtement les risques de collision et pourquoi les véritables collisions proviennent de générateurs défectueux, et non des mathématiques.

La question de l'architecte : aurons-nous un jour un doublon ? — d'où vient l'inquiétude et pourquoi la réponse dépend du générateur

L'architecte demande : si nous générons 10 millions d'UUID par jour pendant dix ans, aurons-nous un jour un double ? La réponse honnête est : presque certainement pas, si le générateur est cryptographiquement sécurisé ; presque certainement oui, si le générateur est en panne. Les mathématiques de la RFC 9562 sont valables : un v4 UUID avec 122 bits aléatoires a une probabilité de collision d'environ n² / 2 à la puissance 123, où n est le nombre d'identifiants générés. Pour la plupart des systèmes réels, cette probabilité est négligeable. Le problème est que cette formule suppose que chaque bit est véritablement aléatoire. Si le générateur fuit, se répète ou a été amorcé de manière prévisible, la formule est fausse et les doublons deviennent inévitables. La disposition 128-bit comprend quatre bits de version (0100 pour v4) et deux bits de variante (10 pour RFC 9562), qui sont fixes et définis par la norme.

Pour quels six bits sont parlés - les quatre bits de version et les deux bits de variante, et pourquoi ils sont définis plutôt qu'aléatoires

Cela laisse 122 bits pour le hasard. La formulation est parfois appelée 2 pour les bits aléatoires 122, produisant des valeurs uniques. En utilisant l'approximation du paradoxe d'anniversaire, la probabilité d'au moins une collision parmi n valeurs générées aléatoirement est d'environ n² / 2 au 123ème. Pour n = 1 millions, cela fait (10^6)² / 2^123 = 10^12 / 9. 3 × 10^36, soit environ 10^-25. Pour n = 10 milliards, cela fait toujours environ 10^-16. Ces valeurs ne sont pas « effectivement nulles » ; ils sont "vous n'observerez jamais cela". L'approximation de l'anniversaire donne un moyen concret de calculer le risque : comptez les UUID que vous envisagez de générer, mettez ce nombre au carré, divisez par 2 à la puissance 123. Si le générateur est le crypto.getRandomValues ​​du navigateur, chaque bit est soutenu par l'entropie du système d'exploitation. Si c'est un Math.

L'approximation de l'anniversaire en termes simples : la probabilité d'au moins une collision entre n identifiants est d'environ n carré divisé par 2 par 123

Pour un UUID produit par un générateur d'états inadapté ou répété, le modèle mathématique s'effondre car son hypothèse d'indépendance est fausse. Une graine de test corrigée, un appareil copié ou un instantané de processus peuvent rejouer les valeurs même si le texte porte toujours le quartet version-4. Ce sont des défauts d'implémentation, et non une preuve que le calcul du champ 122 était erroné. Une autre source banale copie le même identifiant littéral dans plusieurs appareils et fusionne ensuite leurs données. Lorsque vous recherchez un doublon, conservez le générateur, la politique de départ, le cycle de vie du processus et l'historique des importations. Ne passez pas d'une valeur répétée à une affirmation selon laquelle la sortie CSPRNG indépendante a épuisé l'espace UUID.

Exemple concret : intégrer un taux de génération et une période de temps indiqués dans l'approximation, chaque étape étant affichée afin que vous puissiez remplacer vos propres chiffres

Processus de fork sans resynchronisation à état aléatoire. Un bug où Math.random était utilisé à la place de crypto.getRandomValues. Un dispositif de test fabriqué à la main avec le même UUID sur plusieurs rangées et qui a été accidentellement utilisé en production. Une ancienne version d'une bibliothèque UUID qui présentait une limitation de plage ou un bug d'état. Aucun de ces scénarios n'implique les mathématiques d'approximation d'anniversaire ; ils impliquent une mise en œuvre interrompue ou des erreurs opérationnelles. Calculez honnêtement le risque de collision pour votre système : comptez le taux de génération de UUID (par seconde, par jour, par an), projetez-le sur la durée de fonctionnement du système et insérez le total dans la formule d'anniversaire. Si votre système génère 100,000 UUID par jour pendant cinq ans (182 millions au total), la probabilité de collision est de (1. 82 × 10^8)² / 2^123 ≈ 3. 3 × 10^-22, ce qui est négligeable.

D'où proviennent réellement les doublons : graines Math.random, machines virtuelles clonées, processus forkés avec état copié et copier-coller dans les appareils

Si vous générez 10 millions par seconde pendant un an (315 billions au total), la probabilité est de (3. 15 × 10^14)² / 2^123 ≈ 10^-10, qui est encore extrêmement petit. Ces estimations supposent que chaque bit est indépendant et aléatoire. Le générateur ToolAcre utilise crypto.getRandomValues, qui vous offre un caractère aléatoire soutenu par CSPRNG ; l'opération est la seule partie à laquelle vous devez faire confiance. Ne comptez jamais sur la probabilité de collision comme excuse pour ignorer les contrôles d’autorisation appropriés. Un UUID n'est pas un mot de passe, ni un jeton d'accès, ni un secret même s'il s'agit de 122 bits aléatoires. Le caractère unique est l'avantage ; l'imprévisibilité est une propriété distincte (et plus importante) qui empêche de deviner. Les mathématiques d'anniversaire gèrent l'unicité ; il ne traite pas de la durée de vie (ce UUID devrait-il expirer ? ), du secret (doit-il être haché avant le stockage ?) ou de l'autorisation (la possession de ce UUID prouve-t-elle quelque chose sur l'appelant ?). Le générateur ToolAcre vous donne des UUID pris en charge par CSPRNG avec 122 bits aléatoires, ce qui signifie que le caractère unique des mathématiques est valable et que l'imprévisibilité est saine. Tout le reste (validation du jeton, expiration, contrôle d'accès) relève de la responsabilité de votre application. La formule de probabilité suppose l'indépendance de chaque UUID généré par rapport aux générations précédentes. Si votre système génère des identifiants à partir d'une seule instance CSPRNG et que chaque appel tire un nouveau caractère aléatoire du système d'exploitation, l'hypothèse d'indépendance est valable. Si votre système utilise un état CSPRNG mis en cache ou un générateur amorcé sans réamorçage du système d'exploitation, l'hypothèse échoue. Le risque de collision augmente considérablement si la source d'entropie est épuisée (ce qui se produit sur certains systèmes embarqués ou machines virtuelles sous charge) ou si l'état aléatoire n'est jamais réinitialisé entre les processus (processus bifurqué sans ré-amorçage du CSPRNG).

Ce que cela ne couvre pas : l'unicité des v1 et v7, qui repose sur des horodatages et des séquences d'horloge plutôt que sur le seul caractère aléatoire.

La solution de secours ToolAcre appelle crypto.getRandomValues ​​pour chaque tableau d'octets et ne contient aucun état PRNG au niveau de l'application. Les éléments internes de la plateforme restent sous la responsabilité du navigateur et du système d'exploitation. La simulation de collisions avec de vrais générateurs montre la différence entre la théorie et la pratique. Un générateur construit avec Math.random à partir de la même graine produira des séquences identiques ; vous verrez la première collision UUID dans quelques centaines à quelques milliers de valeurs générées, pas après les valeurs 2^60 (la racine carrée de 2^122) comme le prédit l'approximation de l'anniversaire. Un générateur utilisant crypto.getRandomValues ​​à partir de l'entropie sonore du système d'exploitation ne produira des collisions que lorsque la probabilité théorique deviendra inévitable (environ 2^60 UUID), un nombre si grand que vous ne l'atteindrez jamais. Un générateur utilisant une source d'entropie faible ou réutilisée (courante dans les bibliothèques UUID ou les frameworks de test mal implémentés) produira des collisions quelque part entre les deux.

À retenir : faites confiance aux mathématiques, auditez le générateur – le générateur ToolAcre utilise le CSPRNG du navigateur, qui est la partie qui ne doit pas être falsifiée.

Un test par lots peut détecter une implémentation qui renvoie une constante ou rejoue une séquence évidente, mais un échantillon réussi ne peut pas prouver l'unicité future. Les systèmes de production doivent toujours imposer une contrainte unique partout où des identifiants en double corrompent les données. Les importations méritent une attention particulière car deux systèmes sources valides peuvent déjà contenir le même identifiant littéral et les appareils peuvent être copiés à travers les environnements. Les tests de ToolAcre vérifient qu'un lot de 500 contient 500 valeurs distinctes ; il s'agit d'un contrôle de régression pour cette implémentation, pas d'une garantie statistique. Si un doublon apparaît, conservez les preuves et inspectez les chemins de génération, d’importation, de montage et de stockage avant d’attribuer une cause.