Générateur ULID - Créez des ID Uniques et Triables en Ligne Gratuitement
Outil gratuit de génération ULID qui crée instantanément des identifiants uniques et triables. Générez des ULID cryptographiquement sécurisés pour bases de données, API et systèmes distribués en ligne.
Générateur ULID
Documentation
Qu’est-ce qu’un ULID ?
Un ULID (identifiant universellement unique et triable lexicographiquement) est un code de 26 caractères utilisé pour identifier un enregistrement dans une base de données ou un événement dans un système distribué. Il combine l’heure actuelle avec des données aléatoires. Ainsi, une liste de ULID triés par ordre alphabétique se retrouve triée selon l’heure de création de chacun. Un générateur de ULID est un outil qui produit ces codes.
Structure d’un ULID
Un ULID comporte deux parties, écrites l’une à la suite de l’autre sans séparateur :
- Horodatage (10 caractères) : nombre de millisecondes écoulées depuis le 1er janvier 1970 (l’époque Unix), sur 48 bits au maximum.
- Aléa (16 caractères) : 80 bits de données aléatoires, ajoutés pour que deux ULID créés au cours de la même milliseconde soient presque certainement différents.
Les deux parties utilisent l’alphabet Base32 de Crockford : les chiffres 0 à 9 et les lettres A à Z, à l’exception des lettres I, L, O et U. Ces quatre lettres sont exclues, car elles peuvent être confondues avec les chiffres 0 et 1, ou entre elles. Le résultat est une chaîne courte, facile à lire à voix haute et utilisable directement dans une URL.
Comment calculer un ULID
Un générateur de ULID construit un identifiant en trois étapes.
- Lire l’heure actuelle en millisecondes depuis l’époque Unix. Il s’agit d’un nombre sur 48 bits.
- Générer 80 bits de données aléatoires, normalement à l’aide d’un générateur de nombres aléatoires sécurisé sur le plan cryptographique, ce qui donne 10 octets aléatoires.
- Encoder séparément les deux parties avec l’alphabet Base32 de Crockford : l’horodatage de 48 bits devient une chaîne de 10 caractères et la valeur aléatoire de 80 bits devient une chaîne de 16 caractères. Les deux chaînes encodées sont assemblées pour former le ULID final de 26 caractères.
L’encodage lit le nombre par groupes de 5 bits, car chaque caractère Base32 représente l’une des 32 valeurs possibles (2^5 = 32). Dix caractères peuvent contenir jusqu’à 50 bits, ce qui suffit pour l’horodatage de 48 bits. Seize caractères contiennent exactement 80 bits, ce qui correspond à la partie aléatoire sans aucun bit restant.
Exemple détaillé
Supposons qu’un générateur de ULID s’exécute à l’horodatage 1712345678901 (millisecondes depuis l’époque Unix) et tire les octets aléatoires [12, 240, 88, 3, 199, 45, 6, 231, 128, 17].
Étape 1 – encoder l’horodatage. Diviser plusieurs fois 1712345678901 par 32, en prenant le reste à chaque fois et en lisant les chiffres du dernier au premier (il s’agit d’une conversion de base standard). Cela produit la chaîne de 10 caractères 01HTQW311N.
Étape 2 – encoder l’aléa. Regrouper les 10 octets aléatoires en un flux de 80 bits, puis lire 5 bits à la fois en convertissant chaque groupe de 5 bits en caractère Base32. Cela produit la chaîne de 16 caractères 1KR5G0Y75M3EF00H.
Étape 3 – assembler les parties. Le ULID final est :
101HTQW311N 1KR5G0Y75M3EF00H
2Il s’écrit sans espace : 01HTQW311N1KR5G0Y75M3EF00H, soit 26 caractères au total.
Utiliser ce générateur
Le générateur s’exécute dans le navigateur. Chaque ULID est construit à partir de l’horloge du navigateur et de 80 bits aléatoires nouvellement produits par le générateur de nombres aléatoires cryptographiques du navigateur. Aucun identifiant n’est donc envoyé à un serveur ni récupéré depuis un serveur.
- Nombre de ULID accepte un nombre entier compris entre 1 et 50. La valeur par défaut est 1.
- Générer un ULID produit un nouveau lot. Modifier le nombre produit également un nouveau lot.
- Copier sur un résultat copie ce seul ULID. Lorsque plusieurs ULID sont affichés, Tout copier copie la liste complète, avec un ULID par ligne.
- Réinitialiser rétablit le nombre à 1 et génère un nouveau ULID.
Sous les résultats, le panneau Structure du ULID sépare le premier ULID du lot en deux parties : les 10 premiers caractères (l’horodatage) et les 16 derniers (l’aléa).
ULID ou UUID
| Fonctionnalité | ULID | UUID (version 4) |
|---|---|---|
| Longueur | 26 caractères | 36 caractères (avec des traits d’union) |
| Triable selon l’heure de création | Oui | Non |
| Encodage | Base32 de Crockford | Hexadécimal |
| Contient un horodatage | Oui (48 bits) | Non |
| Sûr pour les URL sans échappement | Oui | Oui |
Les deux formats visent à produire des identifiants uniques entre les systèmes, sans autorité centrale attribuant les numéros. La principale différence pratique concerne le tri : comme un ULID commence par un horodatage, trier des ULID comme du texte les trie également par heure. Un UUID aléatoire ne possède pas cette propriété, puisque chacune de ses parties est aléatoire.
Utilisations courantes
- Clés primaires de base de données : les ULID permettent à une base de données d’indexer les nouvelles lignes dans un ordre proche de celui de leur insertion, ce que de nombreux moteurs de base de données traitent plus efficacement que des clés entièrement aléatoires.
- Systèmes distribués : plusieurs serveurs peuvent générer des ULID indépendamment, sans coordination avec un compteur central, et les résultats restent presque certainement uniques.
- Journaux d’événements : comme les ULID sont triables par heure, une liste d’identifiants d’événements peut aussi servir de chronologie approximative.
- Identifiants d’API et de fichiers : le format fixe de 26 caractères, compatible avec les URL, s’utilise facilement dans les adresses web et les noms de fichiers.
Les formats d’identifiants apparentés comprennent KSUID, qui encode également un horodatage pour permettre le tri, et les identifiants Snowflake, utilisés par Twitter et d’autres services, qui combinent un horodatage, un identifiant de machine et un compteur.
Exemples de code
Chaque exemple ci-dessous construit un ULID de la manière décrite par la spécification ULID : encoder l’horodatage de 48 bits sous forme de 10 caractères Base32 de Crockford, encoder 80 bits d’aléa sous forme de 16 caractères supplémentaires, puis assembler les deux parties.
JavaScript
1const ENCODING_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
2
3function encodeULID(time, randomBytes) {
4 // Timestamp: 48 bits -> 10 characters
5 let timestampStr = '';
6 let t = time;
7 for (let i = 0; i < 10; i++) {
8 timestampStr = ENCODING_CHARS[t % 32] + timestampStr;
9 t = Math.floor(t / 32);
10 }
11
12 // Randomness: 80 bits -> 16 characters
13 let result = timestampStr;
14 let bits = 0;
15 let bitCount = 0;
16 for (let i = 0; i < 10; i++) {
17 bits = (bits << 8) | randomBytes[i];
18 bitCount += 8;
19 while (bitCount >= 5) {
20 bitCount -= 5;
21 result += ENCODING_CHARS[(bits >> bitCount) & 0x1f];
22 }
23 }
24 return result;
25}
26
27function generateULID() {
28 const randomBytes = crypto.getRandomValues(new Uint8Array(10));
29 return encodeULID(Date.now(), randomBytes);
30}
31
32console.log(generateULID());
33Python
1import os
2import time
3
4ENCODING_CHARS = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
5
6def encode_ulid(time_ms, random_bytes):
7 # Timestamp: 48 bits -> 10 characters
8 chars = []
9 t = time_ms
10 for _ in range(10):
11 chars.append(ENCODING_CHARS[t % 32])
12 t //= 32
13 timestamp_part = "".join(reversed(chars))
14
15 # Randomness: 80 bits -> 16 characters
16 bits = 0
17 bit_count = 0
18 random_part = []
19 for byte in random_bytes:
20 bits = (bits << 8) | byte
21 bit_count += 8
22 while bit_count >= 5:
23 bit_count -= 5
24 random_part.append(ENCODING_CHARS[(bits >> bit_count) & 0x1F])
25
26 return timestamp_part + "".join(random_part)
27
28def generate_ulid():
29 return encode_ulid(int(time.time() * 1000), os.urandom(10))
30
31print(generate_ulid())
32Java
1import java.security.SecureRandom;
2import java.time.Instant;
3
4public class ULIDGenerator {
5 private static final SecureRandom random = new SecureRandom();
6 private static final char[] ENCODING_CHARS =
7 "0123456789ABCDEFGHJKMNPQRSTVWXYZ".toCharArray();
8
9 public static String generateULID() {
10 long timestamp = Instant.now().toEpochMilli();
11 byte[] randomBytes = new byte[10];
12 random.nextBytes(randomBytes);
13
14 // Timestamp: 48 bits -> 10 characters
15 char[] timestampChars = new char[10];
16 long t = timestamp;
17 for (int i = 9; i >= 0; i--) {
18 timestampChars[i] = ENCODING_CHARS[(int) (t % 32)];
19 t /= 32;
20 }
21
22 // Randomness: 80 bits -> 16 characters
23 StringBuilder result = new StringBuilder(new String(timestampChars));
24 long bits = 0;
25 int bitCount = 0;
26 for (byte b : randomBytes) {
27 bits = (bits << 8) | (b & 0xFF);
28 bitCount += 8;
29 while (bitCount >= 5) {
30 bitCount -= 5;
31 result.append(ENCODING_CHARS[(int) ((bits >> bitCount) & 0x1F)]);
32 }
33 }
34 return result.toString();
35 }
36
37 public static void main(String[] args) {
38 System.out.println(generateULID());
39 }
40}
41Foire aux questions
À quoi sert un ULID ?
Un ULID sert d’identifiant unique pour une ligne de base de données, une ressource d’API ou un événement enregistré, lorsque le tri selon l’heure de création est également utile.
Quelle est la longueur d’un ULID ?
Un ULID comporte toujours 26 caractères : 10 caractères pour l’horodatage et 16 pour la partie aléatoire.
Quel encodage utilise un ULID ?
Un ULID utilise l’alphabet Base32 de Crockford, composé des chiffres 0 à 9 et des lettres A à Z, avec les lettres I, L, O et U supprimées pour éviter toute confusion avec d’autres caractères.
Quelle est la différence entre un ULID et un UUID ?
Un ULID se trie selon l’heure de création et comporte 26 caractères. Un UUID aléatoire (version 4) ne se trie pas selon l’heure et comporte 36 caractères, traits d’union compris.
Quelle est la probabilité d’une collision entre deux ULID ?
Les 80 bits d’aléa rendent les collisions extrêmement improbables. Il faudrait générer environ 1,3 billion de ULID au cours de la même milliseconde pour atteindre une probabilité de 50 % que deux d’entre eux correspondent.
Les ULID peuvent-ils être générés sans connexion Internet ?
Oui. Un ULID nécessite uniquement l’horloge locale et un générateur de nombres aléatoires. Il peut donc être créé entièrement hors ligne.
Références
- « Spécification ULID. » GitHub, https://github.com/ulid/spec.
- « Encodage Base32 de Crockford. » http://www.crockford.com/base32.html.