Générateur d'UUID

Générez des UUID v4 ou v7 classés dans le temps et inspectez tout UUID que vous possédez déjà.

5

UUID aléatoires

    Analyser un UUID

    Collez-en un pour voir de quelle version il s’agit et ce qu’il contient, le cas échéant.

    Les versions, et les deux qui comptent

    Il y en a huit, et pour un nouveau projet le choix se joue vraiment entre deux d’entre elles. Les autres méritent d’être reconnues quand on en croise une dans un vieux système.

    VersionConstruite à partir deÀ utiliser quand
    v4122 bits aléatoiresVous avez besoin d’imprévisible. Le choix par défaut pour les jetons et les identifiants.
    v7Horodatage + aléaVous avez besoin d’une clé de base de données. Elle se trie par date de création.
    v1Horodatage + adresse MACAncienne. Elle divulgue la machine et l’heure.
    v3 / v5Hachage d’un espace de noms et d’un nomVous voulez que la même entrée donne toujours le même identifiant.
    v6v1, réordonnéeVous migrez des données v1 en voulant qu’elles se trient.
    v8Ce que vous décidezPresque jamais.

    Le problème de l’index, la vraie raison d’être de la v7

    C’est l’argument pratique, et il vaut mieux le comprendre que le prendre pour argent comptant.

    Une clé primaire de base de données est stockée dans un arbre B, ordonnée. Insérez des entiers consécutifs et chaque nouvelle ligne atterrit sur le bord droit : une page reste chaude en mémoire, l’arbre grandit proprement, et les écritures coûtent peu.

    Insérez des UUID v4 et chaque ligne atterrit n’importe où. Des pages sont touchées dans tout l’arbre, chacune doit être lue avant d’être écrite, et les pages se scindent à mesure qu’elles se remplissent. Sur une table d’une certaine taille, le débit d’insertion chute nettement et l’index se fragmente — l’effet est bien documenté, et c’est ce qui a valu leur réputation aux clés UUID.

    La v7 corrige cela en plaçant l’horodatage en tête. Générez-en quelques-uns ci-dessus avec v7 sélectionné et observez le préfixe commun : les valeurs créées à des instants proches sont voisines, si bien que les insertions s’ajoutent en fin d’index comme le ferait un entier, tout en restant uniques à l’échelle mondiale. Vous conservez la propriété qui rendait les UUID séduisants — produire un identifiant n’importe où, sans coordination — sans la payer à chaque écriture.

    Pour être précis : l’ordre est garanti entre millisecondes, pas à l’intérieur d’une même milliseconde. Deux UUID v7 produits dans la même milliseconde sont ordonnés par leur queue aléatoire, ce que le RFC 9562 autorise, en permettant en option aux implémentations de resserrer cela avec un compteur. Cela ne change rien à l’argument de localité d’index, qui ne dépend que de l’horodatage de tête.

    Le coût qui subsiste dans les deux cas : 16 octets contre 4 ou 8, répliqués dans chaque index qui référence la clé. Sur une grande table comportant plusieurs clés étrangères, cela fait du disque bien réel.

    Ce que la v7 divulgue

    L’horodatage est lisible par quiconque détient l’identifiant. Collez un UUID v7 dans l’inspecteur ci-dessus et il vous indiquera la milliseconde de sa création.

    Généralement sans conséquence. Parfois non : un identifiant v7 dans une URL publique révèle quand un enregistrement a été créé, ce qui peut suffire à déduire des rythmes d’inscription, des volumes de commandes, ou qu’un document a été antidaté. Si cela compte, la répartition évidente est v4 pour tout ce qui est visible par l’utilisateur et v7 pour les clés internes.

    Là où l’aléa doit être réel

    L’arithmétique des collisions que tout le monde cite — 2,7 trillions avant d’avoir une chance sur deux de voir une collision — suppose 122 bits véritablement aléatoires. C’est un énoncé sur le format, pas sur votre implémentation.

    Un UUID bâti sur Math.random() n’a ni l’entropie ni l’imprévisibilité que ce chiffre laisse croire, et les collisions constatées en production ont pour ainsi dire toujours été cela plutôt que de la malchance. Deux processus lancés dans la même seconde avec la même graine produisent la même suite.

    Cette page utilise crypto.randomUUID() là où il existe, et crypto.getRandomValues sinon. Il vaut la peine de vérifier ce qu’emploie votre propre code, surtout si des UUID tiennent lieu de jetons : un identifiant de réinitialisation de mot de passe prévisible, c’est une prise de contrôle complète du compte.

    Les stocker efficacement

    La forme textuelle de 36 caractères est pratique et dispendieuse. Les solutions de rechange, toutes pour les mêmes 128 bits :

    • Type UUID natif — Postgres en a un, et il stocke 16 octets. Utilisez-le.
    • `BINARY(16)` — l’équivalent MySQL, environ la moitié du stockage d’un CHAR(36).
    • Base64 — 22 caractères, quand il faut du texte et que la longueur compte.
    • Base32 — 26 caractères, insensible à la casse, ce qu’il vous faut si un humain doit un jour en lire un à voix haute.

    À voir aussi

    Pour des secrets qu’une personne doit saisir plutôt qu’une machine stocker, le générateur de mots de passe puise à la même source aléatoire. Pour lire l’horodatage d’un UUID v7 dans un autre format, le convertisseur d’horodatage prend le relais.

    Questions sur les UUID

    Deux UUID peuvent-ils entrer en collision ?

    En principe oui ; en pratique non, à condition que le hasard soit réel. Un UUID v4 comporte 122 bits aléatoires, et vous devrez en générer environ 2,7 quintillions avant d'atteindre une probabilité de 50 % d'une seule collision, soit environ un milliard par seconde pendant 85 ans. L’échec réaliste n’est jamais mathématique : c’est une source aléatoire faible. Un UUID construit sur Math.random() ou sur un PRNG mal amorcé peut entrer en collision, c'est pourquoi cette page utilise la source cryptographique du navigateur.

    Dois-je utiliser un UUID comme clé primaire de base de données ?

    Cela dépend de la version et la différence est grande. Un UUID v4 est aléatoire, donc les insertions consécutives atterrissent à des points aléatoires dans un index B-tree : les pages sont divisées, l'index se fragmente et le débit d'écriture diminue de manière mesurable sur une grande table. Un UUID v7 commence par un horodatage en millisecondes, donc les insertions s'ajoutent à la fin comme un entier à incrémentation automatique tout en conservant l'unicité globale. Si vous voulez des clés UUID, utilisez la version v7. L'autre coût s'applique aux deux : 16 octets contre 4 ou 8 pour un entier, sur chaque index qui le référence.

    Qu'est-ce que l'UUID v7 et est-il encore sûr à utiliser ?

    Ordonné dans le temps : 48 bits de millisecondes Unix suivis de 74 bits aléatoires, normalisés dans la RFC 9562 en mai 2024. Il s'agit d'un standard publié pris en charge dans Postgres actuel, dans la plupart des écosystèmes linguistiques et dans un bon nombre de bibliothèques. Il s'agit d'une valeur par défaut raisonnable pour les nouveaux travaux. La seule propriété à prendre en compte est qu'elle intègre une heure de création, donc un identifiant v7 dans une URL révèle à peu près quand l'enregistrement a été créé.

    Un UUID est-il suffisamment sécurisé pour être utilisé comme jeton ?

    Un UUID v4 provenant d'une source cryptographique possède 122 bits d'entropie, ce qui est plus que suffisant pour un lien de réinitialisation de mot de passe ou un identifiant de session. Deux mises en garde. Premièrement, la source doit réellement être cryptographique – crypto.randomUUID l’est, la plupart des implémentations de bibliothèques le sont, et tout ce qui est construit sur Math.random() ne l’est pas. Deuxièmement, les autres versions ne conviennent pas : la v1 intègre un horodatage et historiquement une adresse MAC, les v3 et v5 sont des hachages déterministes de leurs entrées, et la v7 divulgue son heure de création. Si cela doit être indevinable, utilisez la v4.

    Pourquoi un UUID comporte-t-il 36 caractères alors qu'il ne fait que 16 octets ?

    Parce qu'il est écrit en hexadécimal — deux caractères par octet, donc 32 — plus quatre tirets. Certains systèmes stockent les 16 octets bruts à la place, ce à quoi sert MySQL BINARY(16) et divise environ par deux le stockage. D'autres utilisent un encodage de texte plus court : Base64 donne 22 caractères, Base32 en donne 26 et n'est pas sensible à la casse. Ce sont tous les mêmes 128 bits portant des vêtements différents.

    Dernière vérification . Vous avez repéré quelque chose de dépassé ? Dites-le-nous.