Generator ULID

Generuj identyfikatory ULID online: 26-znakowe identyfikatory w formacie Crockford Base32 z 48-bitowym czasem i 80 bitami losowymi.

Format
Wygenerowane identyfikatory
Gotowe. Generuj identyfikatory ULID w przeglądarce.

Jak budowany jest ten identyfikator

Układ
26 znaków Crockford Base32: 10 znaków czasu, po których następuje 16 znaków losowych.
Entropia
80 losowych bitów po 48-bitowym znaczniku czasu w milisekundach.
Czas
Tak. Pierwsze 10 znaków koduje czas w milisekundach, a porządek leksykalny odpowiada chronologii.
Ryzyko kolizji
Losowa końcówka ma 80 bitów; ryzyko kolizji zależy głównie od liczby identyfikatorów tworzonych w tej samej milisekundzie.
Przykład
01M12BRQEBBKZ0QDJVDCNHD9AC

Identyfikatory są generowane lokalnie przy użyciu silnego generatora losowości w przeglądarce. Nic nie jest wysyłane do BroBroGo.

Najczęściej zadawane pytania (FAQ)

Do czego przydaje się ULID?

ULID jest kompaktowy, przyjazny dla adresów URL i może być sortowany chronologicznie jako zwykły tekst, co jest przydatne w logach, kluczach obiektów i rekordach, które powinny być uporządkowane według czasu utworzenia.

Czy ULID to to samo co UUID v7?

Nie. Oba formaty zawierają czas w milisekundach, ale ULID używa kodowania Crockford Base32 i ma 26 znaków, podczas gdy UUID v7 zachowuje standardowy szesnastkowy kształt UUID.

Generator ULID – identyfikatory krótsze, sortowalne i bezpieczne dla adresów URL

Strona ULID Generator pozwala wybrać format ULID, określić liczbę potrzebnych identyfikatorów (od 1 do 100) i natychmiast otrzymać listę unikalnych, sortowalnych czasowo 26‑znakowych ciągów. Każdy identyfikator jest gotowy do skopiowania pojedynczo lub wszystkie naraz.

Czym ULID różni się od innych formatów na tym samym narzędziu

Najważniejszą różnicą jest długość i sposób kodowania. ULID ma 26 znaków, podczas gdy UUID ma 36 (z czterema łącznikami). ULID używa wyłącznie alfabetu Crockford base32 – cyfr 0‑9 oraz liter A‑Z z pominięciem I, L, O, U – co sprawia, że identyfikatory są niezależne od wielkości liter i nie zawierają łączników. Dzięki pierwszych dziesięciu znakom, które kodują znacznik czasu z dokładnością do milisekundy, ULID‑y są leksykograficznie sortowalne według czasu utworzenia. Są też bezpieczne dla adresów URL bez potrzeby escapowania.

W przeciwieństwie do innych formatów na tej stronie, ULID nie oferuje przełączników wielkości liter ani opcji dodawania łączników – one po prostu nie występują. Losowy komponent zajmuje pozostałe 16 znaków (80 bitów), a całkowita wartość bazowa to 128 bitów.

Wewnętrzna struktura ULID – podział 128 bitów

Każdy ULID składa się z dwóch części:

  • Część czasowa (pierwsze 10 znaków): 48‑bitowy znacznik czasu w milisekundach. Okres ten wystarcza na około 8 925 lat od epoki UNIX (1 stycznia 1970), czyli do roku 10895.
  • Część losowa (pozostałe 16 znaków): 80 bitów losowości generowanej przez crypto.getRandomValues() w przeglądarce.

Przykład: 01BX5ZZKBKACTAV9WEVGEMMVRY. Pierwsze 10 znaków (01BX5ZZKBK) to zakodowany czas, reszta to losowe dane.

Dzięki tej konstrukcji ULID‑y są monotonicznie rosnące w czasie – nowe identyfikatory mają zwykle większą wartość leksykograficzną niż starsze. Należy jednak pamiętać, że generowane w tej samej milisekundzie mogą wystąpić w dowolnej kolejności, ponieważ losowa część nie jest gwarantowana jako monotoniczna dla identycznych znaczników czasu (chyba że implementacja dodaje sekwencjonowanie, co nie jest tu zakładane).

Porównanie z UUID v4 i UUID v7

Cecha UUID v4 UUID v7 ULID
Długość tekstowa 36 znaków z łącznikami 36 znaków z łącznikami 26 znaków bez łączników
Wielkość liter wielkie/małe (wersja kanoniczna mała) wielkie/małe niezależna od wielkości (base32)
Łączniki 4 (obowiązkowe) 4 (obowiązkowe) brak
Sortowalność nie tak (znacznik czasu w bitach) tak (leksykograficznie)
Bezpieczeństwo URL wymaga escapowania dla { i }? (nie, ale łączniki są bezpieczne) bezpieczne bezpieczne bez escapowania
Wielkość przestrzeni 122 bity losowe 48 bitów czasu + 74 losowe 48 bitów czasu + 80 losowych
Całkowity rozmiar 128 bitów 128 bitów 128 bitów

UUID v4 jest całkowicie losowy – nie można go sortować po czasie. UUID v7 wprowadza znacznik czasu, ale zachowuje 36‑znakowy format z łącznikami. ULID oferuje tę samą 128‑bitową przestrzeń, ale w znacznie krótszej reprezentacji. Dla bazy danych oznacza to mniejszy indeks i szybsze operacje porównania.

Sortowalność a wydajność indeksów B‑drzew

W systemach baz danych, gdzie klucze główne są generowane losowo (jak UUID v4), indeksy B‑drzewa cierpią na fragmentację – nowe wpisy trafiają w losowe strony, powodując częste podziały i reorganizacje. ULID‑y, będąc monotonicznie rosnącymi, są wstawiane na końcu indeksu, co znacząco poprawia wydajność zapisu, zwłaszcza przy dużych wolumenach danych.

Przykład: w PostgreSQL, gdy tabela ma indeks na kolumnie UUID v4, każda nowa transakcja może trafić do innej strony, wywołując konflikty blokad. Dla ULID‑ów, ponieważ wartości są rosnące, konflikty są minimalne. Różnica w wydajności może sięgać kilkudziesięciu procent przy dużym obciążeniu.

Prawdopodobieństwo kolizji – matematyczna strona

Przy 80‑bitowej losowości (część randomowa) prawdopodobieństwo kolizji jest niezwykle niskie. Dla danego znacznika czasu (tej samej milisekundy):

\begin{align*} n & – liczba wygenerowanych ULID-ów w tej milisekundzie P(kolizja) & ≈ 1 - e^(-(n(n-1)) / (2 × 2⁸⁰)) \end{align*}

Dla 1 miliona identyfikatorów w jednej milisekundzie (co jest niemożliwe w zwykłej przeglądarce) prawdopodobieństwo kolizji wynosi około 1.3 × 10⁻¹². Dla 100 identyfikatorów (maksymalna wartość na stronie) jest ono praktycznie zerowe: około 10⁻²².

To oznacza, że nawet przy bardzo wysokiej częstotliwości generowania kolizje są w praktyce niemożliwe. Jednak dla formalności: generator używa crypto.getRandomValues(), który jest oparty na entropii systemowej i zapewnia kryptograficznie silną losowość.

Bezpieczeństwo URL i kodowanie Crockford base32

Wszystkie znaki używane w ULID (0‑9, A‑Z z wyłączeniem I, L, O, U) są bezpieczne w adresach URL zgodnie z RFC 3986 – należą do kategorii znaków unreserved. Oznacza to, że nie wymagają procentowego kodowania (escapowania) w ścieżkach URL, parametrach zapytania ani fragmentach.

Porównajmy z UUID: znaki -, {, } (jeśli występują w wersji kanonicznej) nie wymagają escapowania, ale gołę bicze – ULID jest krótszy i prostszy.

Dodatkowo, Crockford base32 eliminuje mylące wizualnie znaki: I i 1, O i 0, L i 1, U i V są rozróżniane (U jest wykluczone). Użytkownik może więc bezpiecznie przepisać ULID ręcznie bez ryzyka pomyłki, a wyszukiwanie w bazie danych nie będzie wrażliwe na wielkość liter (przy odpowiednim indeksie z uwzględnieniem case‑insensitivity).

Generowanie lokalne w przeglądarce – prywatność i bezpieczeństwo

Wszystkie identyfikatory są generowane lokalnie w przeglądarce użytkownika, za pomocą silnej losowości z crypto.getRandomValues(). Żadne dane nie są wysyłane na serwer. To oznacza, że:

  • Nie ma ryzyka przechwycenia identyfikatorów przez zewnętrzny serwer.
  • Generowanie działa nawet w trybie offline (po załadowaniu strony).
  • Każda generacja jest niezależna – serwer nie może przewidzieć, jakie ULID‑y zostaną wygenerowane.

To istotne w kontekście bezpieczeństwa: jeśli identyfikatory są używane jako klucze główne lub tokeny sesji, lokalne generowanie eliminuje jeden wektor ataku (np. podsłuchanie ruchu sieciowego). W przeciwieństwie do serwerowych generatorów ULID, które mogą wyciekać czas tworzenia, tutaj przeglądarka kontroluje cały proces.

Zastosowania w praktyce – kto potrzebuje ULID

  • Deweloperzy aplikacji webowych i mobilnych: potrzebują krótkich, unikalnych identyfikatorów, które można wyświetlić w interfejsie użytkownika bez przesadnego wydłużania adresów URL.
  • Administratorzy baz danych: projektując klucze główne, które poprawiają wydajność zapisu dzięki sortowalności.
  • Architekci systemów rozproszonych: gdzie identyfikatory muszą być unikalne między węzłami, a także sortowalne, aby ułatwić replikację i shardowanie.
  • Projektanci API: chcący udostępniać publiczne identyfikatory, które są trudne do odgadnięcia (losowość) a jednocześnie przyjazne dla człowieka (bez łączników, bez mieszania wielkości liter).

Przykład: w aplikacji e‑commerce, gdzie każdy zamówienie otrzymuje identyfikator, ULID może być używany jako klucz główny w bazie danych, a także w adresie URL (/order/01BX5ZZKBKACTAV9WEVGEMMVRY). Jest 10 znaków krótszy od UUID, co przy milionach zamówień oszczędza miejsce w indeksach i pamięci podręcznej.

FAQ – najczęstsze pytania

1. Czy ULID jest bezpieczny jako klucz główny, jeśli może wystąpić kolizja w tej samej milisekundzie?
Tak. Prawdopodobieństwo kolizji dla 100 identyfikatorów w tej samej milisekundzie jest mniejsze niż 10⁻²². W praktyce dla każdej kolejnej milisekundy znacznik czasu się zmienia, więc losowa część jest w pełni niezależna. Jeśli potrzebujesz gwarantowanej monotonii wewnątrz milisekundy, wybierz format z sekwencjonowaniem (np. ULID z sekwencyjnym licznikiem).

2. Czy mogę używać ULID w adresie URL bez escapowania?
Tak. Wszystkie znaki w ULID są bezpieczne dla URL zgodnie z RFC 3986. Nie ma potrzeby kodowania procentowego.

3. Jak długo wytrzyma 48‑bitowy znacznik czasu?
48 bitów wystarcza na około 8 925 lat od epoki UNIX (1970). To oznacza, że ULID będzie działać bez przepełnienia do roku 10895. Dla porównania, UUID v7 używa tego samego rozmiaru znacznika czasu.

4. Czy ten generator używa crypto.getRandomValues()?
Tak. Wszystkie losowe bity pochodzą z crypto.getRandomValues(), który jest kryptograficznie bezpiecznym generatorem liczb losowych dostępnym w przeglądarkach. Nie używamy Math.random().

5. Dlaczego ULID nie ma opcji dodania łączników?
Ponieważ specyfikacja ULID nie przewiduje łączników. Format jest przeznaczony do bycia 26‑znakowym, ciągłym ciągiem. Dodawanie łączników złamałoby jego strukturę i naruszyło możliwość sortowania leksykograficznego (łączniki mogą być używane jako separatory w innych kontekstach).

6. Czy mogę wygenerować mniej niż 1 lub więcej niż 100 identyfikatorów?
Nie. Strona akceptuje wartości tylko z zakresu 1–100. Wynika to z chęci utrzymania czytelności listy i ograniczenia ryzyka przypadkowego przeciążenia generatora w przeglądarce (choć technicznie może wygenerować dowolną liczbę).