Qu'est-ce que l'ULID et en quoi diffère-t-il des autres identifiants?
La page ulid-generator de cet outil en ligne produit des identifiants ULID (Universally Unique Lexicographically Sortable Identifier) à la demande. Vous choisissez simplement le nombre d’ID souhaité — entre 1 et 100 — et le générateur vous renvoie instantanément une liste de chaînes de 26 caractères, insensibles à la casse, sans tiret, prêtes à être copiées une par une ou en bloc.
Ce qui distingue fondamentalement cette page des autres générateurs du même site (UUID, NanoID, etc.), c’est que l’ULID est un format conçu pour être plus court qu’un UUID (26 caractères contre 36), tout en utilisant exclusivement l’alphabet base32 de Crockford. Cela le rend insensible à la casse et dépourvu de tout séparateur typographique. Les 10 premiers caractères codent un timestamp en millisecondes, ce qui permet un tri lexicographique par ordre de création. De plus, l’ULID est naturellement « URL-safe »: aucun de ses caractères n’a besoin d’être échappé dans une URL. Parce que la spécification ULID interdit déjà les lettres ambiguës et les tirets, l’interface de la page ne propose aucun bouton pour basculer en majuscules ou ajouter des tirets — ces options n’auraient tout simplement pas de sens.
Structure interne d’un ULID: timestamp et aléa
Un ULID repose sur 128 bits, exactement comme un UUID standard. Mais la répartition est différente:
- 48 bits pour le timestamp, exprimé en nombre de millisecondes écoulées depuis l’époque Unix (1er janvier 1970 00:00:00 UTC). Cet entier est codé en base32 de Crockford, ce qui donne les 10 premiers caractères de l’ULID.
- 80 bits pour la composante aléatoire, qui occupe les 16 caractères restants.
La chaîne finale de 26 caractères est donc une concaténation: TTTTTTTTTTRRRRRRRRRRRRRRRR (10 T pour le temps, 16 R pour l’aléa). Par exemple, un ULID typique peut ressembler à 01ARZ3NDEKTSV4RRFFQ69G5FAV.
Grâce à la partie temporelle, deux ULIDs générés à des millisecondes différentes se classent automatiquement dans l’ordre chronologique si on les trie alphabétiquement. En revanche, l’ordre n’est pas garanti pour des identifiants produits dans la même milliseconde: dans ce cas, la composante aléatoire seule détermine l’ordre, et il peut y avoir des inversions. C’est un point important à connaître quand on conçoit des systèmes qui doivent refléter une chronologie stricte.
L’encodage Crockford base32: pourquoi cet alphabet?
L’alphabet base32 de Crockford a été choisi pour minimiser les erreurs de lecture et de saisie par un humain. Il utilise:
- les chiffres
0à9 - les lettres
AàZ, à l’exception deI,L,OetU(pour éviter les confusions avec1,l,0etV)
Le U est exclu car il peut être confondu avec V dans certaines polices. En pratique, un ULID peut être saisi indifféremment en majuscules ou en minuscules: le logiciel de décodage doit accepter les deux. C’est pourquoi le générateur n’affiche pas d’option « majuscules » — l’insensibilité à la casse est une propriété du format, pas un choix d’affichage.
De même, l’absence de tirets n’est pas une option: la spécification ULID ne prévoit aucun séparateur. L’identifiant se présente toujours comme une chaîne continue de 26 caractères.
Comparaison entre ULID, UUID v4 et UUID v7
Voici un tableau récapitulatif des différences majeures entre les trois formats couramment rencontrés:
| Propriété | ULID | UUID v4 | UUID v7 |
|---|---|---|---|
| Longueur (format texte) | 26 caractères | 36 caractères (dont 4 tirets) | 36 caractères (dont 4 tirets) |
| Alphabet | Base32 Crockford (0-9, A-Z sauf I,L,O,U) | Hexadécimal (0-9, a-f) | Hexadécimal (0-9, a-f) |
| Sensibilité à la casse | Insensible (par conception) | Sensible (hexadécimal standard) | Sensible (hexadécimal standard) |
| Tri par date | Oui, lexicographique (timestamp 48 bits) | Non (aléatoire pur) | Oui, grâce à un timestamp (48 bits) |
| Tirets | Non | Oui, format 8-4-4-4-12 | Oui, format 8-4-4-4-12 |
| URL-safe sans échappement | Oui (tous les caractères sont réservés dans RFC 3986) | Non (les tirets sont safe, mais certains caractères sont identiques) | Idem UUID v4 |
L’ULID est donc plus compact que n’importe lequel des UUID. Il partage avec UUID v7 la propriété d’être ordonné temporellement, mais sans les tirets et avec un alphabet moins sujet à confusion. En revanche, UUID v7 est encore jeune (RFC 9562) et son adoption dans les bases de données est en cours, tandis que l’ULID existe depuis plusieurs années dans de nombreuses bibliothèques.
Utilisation en base de données et performances des index B-tree
L’un des arguments les plus forts en faveur de l’ULID pour les développeurs et administrateurs de bases de données est son impact sur les performances d’indexation, en particulier pour les index B-tree (le type d’index par défaut dans la plupart des SGBD relationnels).
Les clés primaires aléatoires, comme celles générées par UUID v4, provoquent une fragmentation des pages d’index: les nouvelles valeurs s’insèrent à des positions aléatoires dans l’arbre, ce qui force des réorganisations fréquentes (split de pages). À l’inverse, les ULIDs étant essentiellement croissants dans le temps (sauf intra-milliseconde), les nouvelles clés s’ajoutent en fin d’index. Les insertions deviennent alors des opérations séquentielles, bien moins coûteuses en écritures et en maintenance.
Ce comportement est particulièrement avantageux pour les tables qui reçoivent de nombreuses insertions, comme les journaux d’événements, les fils d’actualité ou les systèmes de messagerie. Attention toutefois: si plusieurs nœuds génèrent des ULIDs de manière concurrente sur la même milliseconde, l’ordre exact peut varier, mais l’effet global reste très supérieur à celui d’une clé purement aléatoire.
Génération locale, confidentialité et probabilité de collision
Tous les ULIDs produits par cette page sont créés localement dans votre navigateur, en utilisant crypto.getRandomValues() pour la composante aléatoire. Aucune donnée n’est transmise à un serveur: votre liste d’identifiants reste privée et ne quitte jamais votre machine.
Avec 80 bits d’aléa, la probabilité de collision est extrêmement faible. En pratique, si vous générez 1 000 ULIDs par seconde, il faudrait environ 100 millions d’années pour atteindre une chance de 50 % d’en trouver deux identiques. Ce calcul repose sur l’approximation du paradoxe des anniversaires adapté à 80 bits. Pour les 1 à 100 identifiants que l’outil produit en une seule fois, le risque de doublon est rigoureusement nul.
Le générateur n’accepte que des quantités comprises strictement entre 1 et 100. Toute valeur en dehors de cet intervalle est refusée. Si vous changez le format ou le nombre d’IDs, la liste est automatiquement régénérée — il n’y a pas de fonction « ajouter à la liste existante ».
Questions fréquentes
Un ULID est-il garanti unique? Non, comme tout identifiant fondé sur l’aléa, il existe une probabilité (infime) de collision. Avec 80 bits de composante aléatoire et un timestamp, le risque est négligeable pour des usages courants, mais un contrôle d’unicité peut être nécessaire dans les systèmes critiques.
Puis-je utiliser des ULIDs comme clés primaires dans une base de données? Oui, et c’est même un cas d’usage recommandé pour améliorer les performances d’insertion par rapport aux UUID v4. Attention toutefois à ne pas exposer ces clés publiquement si la prédictibilité partielle (timestamp visible) est un problème de sécurité.
Pourquoi l’outil ne propose-t-il pas d’option pour les tirets ou la casse? Parce que la spécification ULID interdit les tirets et impose une insensibilité à la casse. Ajouter ces options serait trompeur: un ULID avec tirets ne serait plus un ULID valide au sens strict.
Quelle est la différence entre ULID et UUID v7? Les deux incluent un timestamp. UUID v7 utilise un format hexadécimal avec tirets et 122 bits (6 bits de version/variante), tandis que l’ULID utilise le base32, 128 bits et aucun tiret. L’ULID est plus court (26 vs 36 caractères) et plus facile à recopier manuellement.
Les ULIDs sont-ils sécurisés pour des identifiants publics? Ils le sont modérément. La partie timestamp permet de déduire la date de création à la milliseconde près. Pour des identifiants qui ne doivent pas révéler d’information temporelle, mieux vaut utiliser un UUID v4 ou un NanoID. Pour des API publiques où la prédictibilité n’est pas critique, l’ULID reste acceptable.
Comment copier un ULID individuellement ou tous à la fois? Dans l’interface, un clic sur un ULID le copie dans le presse-papier. Le bouton « Copier tout » copie la totalité de la liste, et le message « Copied all! » confirme l’action. Les status « Ready. », « Generated. » et « Copied all! » sont affichés en anglais conformément à l’interface de l’outil.