Co je ULID a proč je jiný než ostatní formáty
Stránka ulid-generator nabízí generátor identifikátorů ve formátu ULID (Universally Unique Lexicographically Sortable Identifier). Na rozdíl od UUID, které má 36 znaků včetně čtyř pomlček, ULID používá pouze 26 znaků a žádné oddělovače. Hlavní rozdíl spočívá v abecedě – ULID je postaven na Crockfordově base32 kódování, které používá číslice 0–9 a písmena A–Z s vynecháním vizuálně zaměnitelných znaků I, L, O a U. Tato volba znamená, že ULID je case-insensitive (nezáleží na velikosti písmen) a zároveň URL‑bezpečný – žádný z použitých znaků nevyžaduje procentuální escapování v rámci RFC 3986.
ULID je také lexikograficky řaditelný podle času vzniku. Prvních 10 znaků kóduje milisekundové časové razítko, zbývajících 16 znaků je náhodných. Díky tomu lze ID generovaná v různých milisekundách seřadit jednoduše abecedně, což je zásadní výhoda oproti náhodným UUID v4. Celková bitová délka ULID je 128 bitů – stejně jako UUID, ale v kompaktnějším zápisu.
Vnitřní struktura: časové razítko a náhodná složka
Každý ULID je tvořen dvěma částmi dohromady o 128 bitech:
- Časová část: 48 bitů, zakódovaných do prvních 10 znaků. Umožňuje přesnost na milisekundy a bez problémů pokryje dobu přibližně 108 let od epochy (rok 2025 + 108 let).
- Náhodná část: 80 bitů, zakódovaných do zbývajících 16 znaků. Tyto bity jsou generovány kryptograficky bezpečným generátorem náhodných čísel v prohlížeči – konkrétně
crypto.getRandomValues().
Protože ULID používá Crockfordovo base32, každý znak reprezentuje 5 bitů informace. Deset znaků časové části tedy dává 50 bitů (10 × 5), ale základní časové razítko je 48bitové – mírná rezerva je dána charakterem kódování. Náhodná část využívá plných 80 bitů (16 × 5).
Příklad ULID: 01ARZ3NDEKTSV4RRFFQ69G5FAV
Prvních deset znaků (01ARZ3NDEK) kóduje časové razítko. Pokud bychom jej dekódovali zpět, dostaneme přesný okamžik v milisekundách od Unix epochy. Následujících šestnáct znaků (TSV4RRFFQ69G5FAV) je náhodných.
Crockfordovo base32: proč chybí pomlčky a proč nezáleží na velikosti písmen
Crockfordovo kódování je varianta base32, která se vyhýbá znakům snadno zaměnitelným při ručním přepisu. Konkrétně vynechává:
- I a L (zaměnitelné s 1)
- O (zaměnitelné s 0)
- U (zaměnitelné s V v některých fontech)
Díky tomu je ULID odolný vůči chybám při čtení a zápisu. Zároveň je definován jako case-insensitive – A a a reprezentují stejnou hodnotu. To je výhodné při práci s databázemi, které porovnávají řetězce bez ohledu na velikost písmen (např. PostgreSQL v defaultním módu).
Na rozdíl od UUID, které často obsahuje pomlčky pro lepší čitelnost (např. 550e8400-e29b-41d4-a716-446655440000), ULID pomlčky vůbec nepoužívá. To zjednodušuje parsování a snižuje délku řetězce. Stránka ulid-generator proto nenabízí přepínač pro přidání pomlček – formát je definován bez nich.
Jak nástroj funguje: vstupy, výstupy a chování
Uživatel na stránce ulid-generator nastaví dva parametry:
- Formát: pevně nastaven na ULID (nelze změnit na jiný formát v rámci této stránky).
- Počet ID: celé číslo od 1 do 100 včetně.
Po kliknutí na tlačítko Generovat nástroj vytvoří seznam ULID. Každé ID je zobrazeno jako samostatný řádek, který lze jednotlivě zkopírovat kliknutím. K dispozici je také tlačítko pro hromadné zkopírování všech ID – po jeho použití se zobrazí hláška „Copied all!“.
Stavová hláška se mění podle aktuálního stavu:
- „Ready.“ – po načtení stránky nebo po změně parametrů.
- „Generated.“ – po vygenerování nového seznamu.
Pokud uživatel změní počet ID nebo znovu klikne na Generovat, starý seznam se zahodí a vygeneruje se nový. Všechna ID vznikají přímo v prohlížeči, nikam se neodesílají – kryptografický generátor crypto.getRandomValues() zajišťuje silnou náhodnost bez potřeby serveru.
Srovnání s UUID v4 a UUID v7
Pro lepší pochopení výhod ULID je užitečné srovnání s nejběžnějšími variantami UUID:
| Vlastnost | ULID | UUID v4 | UUID v7 |
|---|---|---|---|
| Délka řetězce | 26 znaků | 36 znaků | 36 znaků |
| Abeceda | Base32 (Crockford) | Hexadecimální | Hexadecimální |
| Pomlčky | Ne | 4 | 4 |
| Řaditelnost podle času | Ano (milisekundy) | Ne | Ano (milisekundy) |
| Case‑sensitive? | Ne | Ne (hex) | Ne (hex) |
| URL‑bezpečný | Ano | Ne (pomlčky) | Ne (pomlčky) |
| Bitová délka | 128 bitů | 128 bitů | 128 bitů |
UUID v7 je podobně jako ULID časově řaditelné, ale stále používá hexadecimální abecedu (16 znaků namísto 32 možných u Crockforda), což prodlužuje výsledný řetězec. UUID v7 také obsahuje pomlčky, které ULID postrádá. Pro databázové indexy, kde záleží na velikosti klíče, je ULID výhodnější – 26 znaků versus 36 znamená úsporu přibližně 28 % v textové reprezentaci.
Na druhou stranu UUID v7 je standardizováno v RFC 4122, zatímco ULID je de facto standard bez oficiální RFC specifikace. Pro většinu aplikací to však není překážkou.
Pravidla a omezení: kolize, řazení v rámci milisekundy a lokální generování
ULID není dokonalý – má několik důležitých vlastností, které je třeba znát:
-
Řazení není striktní v rámci stejné milisekundy. Pokud vygenerujete více ULID ve stejné milisekundě, jejich časová část je totožná. Pořadí pak určuje náhodná složka, která není monotónní. To znamená, že ID ze stejné milisekundy nemusí být seřazena přesně v pořadí vzniku. Pro většinu použití to nevadí, pokud nevyžadujete absolutní sekvenci v rámci jedné milisekundy.
-
Kolizní pravděpodobnost je velmi nízká, ale není nulová. Náhodná složka má 80 bitů, což dává 2^80 možných hodnot (asi 1,2 × 10^24). Pokud generujete 1 000 ULID za sekundu, bude trvat v průměru miliardy let, než dojde ke kolizi (při zanedbání narozeninového paradoxu). Pro běžné aplikace je riziko zanedbatelné.
-
Generování probíhá lokálně v prohlížeči. To je výhoda z hlediska soukromí – žádná data neopouštějí váš počítač. Není potřeba volat žádné API ani se připojovat k serveru. Stačí otevřít stránku a ID jsou k dispozici okamžitě. Tento přístup také znamená, že nástroj funguje offline (po prvním načtení stránky).
-
Omezený počet na jednu dávku: 1 až 100. Stránka akceptuje pouze celočíselný počet v tomto rozmezí. Pokud potřebujete vygenerovat více ID, musíte proces opakovat.
Pro koho je ULID vhodný
ULID nachází uplatnění především v těchto situacích:
- Webové a mobilní aplikace – kratší identifikátory se lépe zobrazují v URL, logách a uživatelském rozhraní.
- Databázové primární klíče – časově řaditelné ID zlepšují výkon B-stromů, protože nové záznamy se vkládají na konec indexu, nikoli náhodně doprostřed jako u UUID v4.
- Distribuované systémy – každý uzel může generovat ULID nezávisle bez koordinace, přičemž ID jsou globálně unikátní (při dostatečné entropii).
- API design – veřejná ID by měla být těžko uhodnutelná, ale zároveň čitelná pro člověka. ULID splňuje oba požadavky – Crockfordova abeceda je bez vizuálních nejasností a 80bitová náhoda znemožňuje hádání.
Pro vývojáře, kteří dosud používali UUID v4 a chtějí kratší, řaditelné identifikátory bez ztráty kvality náhody, je ULID přirozenou volbou.
Často kladené otázky
Je ULID bezpečný pro kritické systémy, kde nesmí dojít ke kolizi?
Pravděpodobnost kolize je extrémně nízká (80 bitů náhody). Pro většinu aplikací je to bezpečné. Pokud však potřebujete absolutní jistotu bez kolizí, je třeba použít centralizovaný sekvenční generátor.
Může se ULID opakovat, pokud generuji na více zařízeních současně?
Ano, teoreticky může – ale pravděpodobnost je stejně nízká jako u UUID v4. Pokud dvě zařízení vygenerují stejnou náhodnou složku ve stejné milisekundě, dojde ke kolizi. V praxi je to ale prakticky vyloučené.
Jaký je rozdíl mezi ULID a UUID v7?
Oba jsou časově řaditelné a používají milisekundové razítko. ULID je kratší (26 vs. 36 znaků) a bez pomlček, zatímco UUID v7 je standardizované v RFC 4122. ULID používá Crockfordovo base32 (32 znaků), UUID v7 hexadecimální (16 znaků). ULID je také URL‑bezpečný bez escapování.
Je možné ULID dekódovat zpět na časové razítko?
Ano, prvních 10 znaků lze dekódovat z Crockfordova base32 na 48bitové číslo, které představuje milisekundy od Unix epochy. Existují online nástroje i knihovny pro tuto konverzi.
Proč nástroj neumožňuje přidat pomlčky nebo změnit velikost písmen?
Protože ULID je definován bez pomlček a jako case‑insensitive. Přidání pomlček by narušilo standardní formát a zbytečně prodloužilo řetězec. Velikost písmen je irelevantní – při porovnání se stejně nebere v úvahu.
Má ULID nějakou oficiální specifikaci?
ULID není standardizován žádnou autoritou (jako IETF), ale existuje specifikace na GitHubu a implementace v mnoha jazycích. Je to de facto standard s jasně definovaným formátem a chováním, který se používá v produkčních systémech.