Potrzebujesz identyfikatora, który nie wejdzie w konflikt z żadnym stworzonym przez kogoś innego, na maszynie, o której nigdy nie słyszałeś, bez pytania kogokolwiek o pozwolenie? To jest właśnie zadanie dla UUID. Jest to 128-bitowa liczba, zapisywana jako 36 znaków w dobrze znanym formacie 8-4-4-4-12, zaprojektowana w całości po to, by żadne dwa identyfikatory nie były takie same, mimo że nic nie koordynuje tego, kto otrzymuje jaki. Ten darmowy generator tworzy je w Twojej przeglądarce: wybierz wersję w polu Wersja, określ ile ich potrzebujesz w polu Liczba i naciśnij Generuj. Strona domyślnie otwiera się na pojedynczym v4, czyli wersji, której oczekuje większość projektów, więc pierwszy identyfikator masz na wyciągnięcie ręki.
Każdy identyfikator jest budowany przez Twoją przeglądarkę przy użyciu Web Crypto API. Wersja 4 wykorzystuje crypto.randomUUID(), jeśli przeglądarka to obsługuje, a w przeciwnym razie crypto.getRandomValues() — czyli kryptograficznie silne źródło losowości, a nie javascriptową pseudolosową funkcję, taką jak Math.random(). Wersja 7 na samym początku umieszcza 48-bitowy znacznik czasu (w milisekundach), po którym następuje 12-bitowy licznik rosnący w obrębie tej samej milisekundy, a na końcu 62 losowe bity. Jest to metoda sortowania opisana w dokumencie RFC 9562; dzięki temu licznikowi partia tysiąca identyfikatorów jest generowana w kolejności, a nie przetasowana. Wersja 1 łączy znacznik czasu z losowym identyfikatorem węzła, który ma ustawiony bit multicastu, więc nigdy nie zawiera adresu Twojej karty sieciowej w sposób, w jaki robiły to oryginalne implementacje z lat 90. Wersje 3 i 5 w ogóle nie są losowe: tworzą one skrót przestrzeni nazw razem z podaną nazwą, używając odpowiednio algorytmów MD5 i SHA-1, a samo haszowanie również odbywa się na Twoim urządzeniu. Nic nie jest wysyłane na serwer, nic nie jest logowane, a po załadowaniu strony narzędzie działa dalej nawet bez połączenia z siecią.
Wersja to pole, które decyduje o wszystkim innym. Wersja 4 to 122 losowe bity bez żadnej struktury — domyślna i właściwa odpowiedź, gdy identyfikator ma być po prostu unikalny. Wersja 7 zachowuje 62 losowe bity, ale zaczyna się od czasu utworzenia, dzięki czemu zbiór takich identyfikatorów układa się w kolejności powstawania; właśnie to sprawia, że jest to wersja po którą sięgamy, gdy identyfikator ma stać się kluczem bazy danych. Wersja 1 to oryginalny schemat oparty na czasie, zachowany tutaj dla systemów, które nadal go wymagają. Wersje 3 i 5 to specyficzna para: są one deterministyczne (co oznacza, że te same dane wejściowe zawsze dają ten sam identyfikator) i wymagają dwóch dodatkowych pól — Przestrzeń nazw, którą jest jedna ze standardowych przestrzeni (DNS, URL, OID i X.500) lub Twoja Własna przestrzeń nazw (UUID), oraz Nazwa, czyli identyfikowany ciąg znaków. Przekaż do v5 przestrzeń nazw URL oraz wartość https://example.com/a, a otrzymasz ten sam UUID dzisiaj, jutro i na maszynie kogoś innego. Z tego powodu Liczba znika, gdy wybrane jest v3 lub v5: tysiąc kopii jednej deterministycznej wartości byłoby tylko tysiącem kopii jednej deterministycznej wartości. Dla każdej innej wersji Liczba przyjmuje wartości od 1 do 1000.
Cztery przełączniki zmieniają kształt wyjścia bez modyfikacji 128 bitów znajdujących się pod spodem. Wielkie litery drukuje cyfry szesnastkowe jako wersaliki, Bez myślników daje kompaktową, 32-znakową formę, którą preferują niektóre kolumny i nazwy plików, a Nawiasy klamrowe otacza wartość znakami { } — to format, który Windows i świat .NET nazywają GUID. W sekcji Opcje zaawansowane, urn:uuid: dodaje prefiks, który sprawia, że jest to formalny URN; wyłącza to Nawiasy klamrowe oraz Bez myślników tak długo, jak jest włączone, ponieważ standard dopuszcza dokładnie jedną formę URN, która jest kanoniczną formą z myślnikami. Format kopiowania decyduje o tym, jak partia danych jest łączona przy jej pobieraniu: po jednym w wierszu, oddzielone przecinkami, lub każda wartość w cudzysłowach i z przecinkiem na końcu, co pozwala wkleić je bezpośrednio do tablicy w kodzie. Pod wynikiem znajduje się linia raportująca losowość w bitach — 122 dla v4, 62 dla v7 — oraz, w przypadku v7, znacznik czasu zakodowany w pierwszym identyfikatorze w partii, dzięki czemu czas wewnątrz wartości jest widoczny, a nie domniemany. Zarówno Kopiuj wszystko, jak i Zapisz do pliku respektują Format kopiowania. Historia przechowuje Twoje ostatnie 10 partii we własnej przeglądarce: kliknij jedną z nich aby ją przywrócić, skopiuj lub usuń pojedynczy wpis, albo wyczyść całość. Wyczyść opróżnia wynik pozostawiając ustawienia bez zmian, a po przekroczeniu 50 identyfikatorów lista staje się jednym, przewijanym blokiem zamiast pięćdziesięciu rzędów.
Najbardziej brzemienną w skutki rzeczą na tej stronie jest różnica między v4 a v7 jako kluczem głównym, i nie jest to kwestia gustu. Indeksy bazy danych to drzewa (np. B-tree) utrzymywane w posortowanym porządku, a to, gdzie w tym porządku wyląduje nowy klucz, decyduje o tym, ile pracy kosztuje jego wstawienie. Klucz v4 jest losowy, więc kolejne wstawienia trafiają do niepowiązanych ze sobą zakamarków indeksu: strony (pages), które były pełne, ulegają podziałowi (page split), fragmenty drzewa utrzymywane przez bazę w pamięci rzadko są tymi, których wymaga następne wstawienie, a sam indeks rośnie wolniej i jest większy oraz bardziej pofragmentowany, niż zasługują na to wiersze, na które wskazuje. Klucz v7 zaczyna się od obecnej milisekundy, więc kolejne wstawienia trafiają obok siebie na prawym skraju drzewa, co jest schematem tworzonym przez autoinkrementującą się liczbę całkowitą i wokół którego zbudowano struktury indeksów. Na tym polega cała ta wymiana: v7 kupuje Ci zachowanie podczas wstawiania typowe dla klucza sekwencyjnego, zachowując jednocześnie właściwość, która w ogóle skłoniła Cię do wyboru UUID, czyli to, że każdy może go wygenerować bez pytania serwera. Kosztem jest to, że czas utworzenia jest teraz możliwy do odczytania z wnętrza identyfikatora, a to, czy ma to znaczenie, jest pytaniem o Twoje dane, a nie o sam format.
Nic nigdy nie sprawdza unikalności UUID; jego rozmiar jest tego gwarancją. Nie ma żadnego rejestru, wywołania serwera, żadnego sprawdzania — generator wytwarza liczbę i ją przekazuje, a powodem, dla którego dwie z nich nie kolidują, jest po prostu fakt, że istnieje 2^122 możliwych wartości v4, co daje liczbę na poziomie około 5,3 sekstyliona. Paradoks dnia urodzin to uczciwy sposób na oszacowanie tej wielkości: potrzebowałbyś około 2,7 tryliona identyfikatorów zanim wystąpiłoby 50% szans na dopasowanie jakichkolwiek dwóch z nich, co przekłada się na miliard nowych UUID w każdej sekundzie przez 86 lat. Warto precyzyjnie określić, co to obiecuje, a czego nie. Jest to gwarancja statystyczna, a nie arytmetyczna, która obowiązuje tylko wtedy, gdy losowość pod spodem jest prawdziwa — źle zainicjowany generator, albo maszyna wirtualna sklonowana razem z jej pulą entropii, łamie tę gwarancję w sposób, którego sam format nie jest w stanie wykryć. Wersja 7 jeszcze bardziej zawęża ten problem: w obrębie jednej milisekundy pojedynczy generator w ogóle nie może się powtórzyć, ponieważ licznik inkrementuje się, zamiast rzucać kośćmi, a pomiędzy niezależnymi generatorami to 62 losowe bity wykonują swoją pracę.
UUID to identyfikator, a nie hasło. Wersja 4 jest nieprzewidywalna, a to kusi ludzi do traktowania jej jako sekretu — linku do resetowania hasła, nieodgadniętego adresu URL, tokenu sesji czy klucza API. Nieprzewidywalność jest faktem, ale poufność to właściwość sposobu obchodzenia się z wartością, a identyfikatory z definicji traktowane są niedbale: znajdują się w adresach URL, które trafiają do historii przeglądarki, logów serwera, nagłówków referer i statystyk, bywają też wklejane w komunikatorach. Inne wersje to jeszcze gorsi kandydaci. Wersja 1 oraz wersja 7 kodują moment powstania, więc każdy, kto jest w ich posiadaniu, wie w przybliżeniu, kiedy zostały stworzone, mogąc tym samym zawęzić sąsiedztwo wszystkiego, co powstało w tym samym czasie. Wersje 3 i 5 są celowo deterministyczne: v5 UUID dla adresu e-mail to nie jest zahaszowany sekret, tylko wartość, którą każdy, kto zna ten sam adres, może obliczyć w sekundę. Używaj UUID do nazywania rzeczy. Używaj generatora haseł, albo tokenów z biblioteki stworzonej do obsługi sekretów, gdy wartość musi pozostać nieznana.
Dlaczego warto wybrać ten generator UUID?
- Generowanie wyłącznie w przeglądarce: identyfikatory powstają na Twoim urządzeniu i nigdy nie są nigdzie wysyłane
- Losowość Web Crypto API: zabezpieczona kryptograficznie, nie zwykłe Math.random()
- Pięć wersji w jednym miejscu: v1, v3, v4, v5 i v7, bez przełączania narzędzi
- Prawdziwie uporządkowane v7: licznik w obrębie milisekundy, zgodnie z opisem RFC 9562
- Deterministyczne v3 i v5 z czterema standardowymi przestrzeniami nazw lub z Twoją własną
- Do 1000 na raz, z kompaktową przewijaną listą po przekroczeniu pięćdziesięciu sztuk
- Każdy powszechny kształt: z myślnikami, goły, wielkie litery, nawiasy klamrowe lub urn:uuid: URN
- Kopiowanie jako linie, przecinki lub ujęte w cudzysłowy wartości do wklejenia wprost do kodu
- Bez limitów i za darmo: żadnej rejestracji, brak limitów użycia, zupełnie nic na naszych serwerach
UUID pojawiają się wszędzie tam, gdzie coś musi zostać nazwane zanim cokolwiek zdąży potwierdzić, że nazwa jest wolna. Kod aplikacji generuje je dla wierszy, które za chwilę wstawi, dzięki czemu obiekt ma tożsamość jeszcze przed trafieniem do bazy danych, a klient może odnosić się do niego, gdy operacja zapisu wciąż trwa. Systemy rozproszone opierają się na nich jeszcze mocniej: kilka usług zapisujących do jednej tabeli, mobilny klient tworzący rekordy w trybie offline w samolocie, kolejka, która musi rozpoznać przetworzoną już wiadomość — żadne z nich nie może czekać na swoją kolej przy współdzielonym liczniku. Wersja 5 odpowiada na inną potrzebę, którą jest stabilny identyfikator wyprowadzony z czegoś, co już posiadasz: ten sam dokument, ten sam URL lub to samo konto zawsze mapuje się na ten sam UUID, więc import można uruchomić dwukrotnie, niczego przy tym nie duplikując. Gdzie indziej są one po prostu formatem wymaganym przez system — identyfikatorem korelacji wplecionym w logi i ślady, nazwą pliku, która nie spowoduje konfliktu gdy uploady od tysiąca użytkowników trafią do jednego bucketa, kluczem rejestru Windows czy testowymi danymi, które muszą wyglądać jak te prawdziwe.
Warto znać kilka uczciwych ograniczeń. Jedna partia to jedna wersja: wartość w polu Wersja stosuje się do wszystkich wygenerowanych elementów, więc generowanie v4 i v7 to dwie osobne partie. To jest generator, nie inspektor — wklejenie UUID w celu odczytania jego wersji lub znacznika czasu nie jest tym, co robi ta strona. Zapisz do pliku zapisuje zwykły plik tekstowy, a nie CSV czy JSON. Wersja 7 otwarcie ujawnia kiedy powstała, co do milisekundy, co jest faktycznym kompromisem, a nie wadą (wersja 1 również w ten sam sposób wycieka czas); jeśli stanowi to problem dla Twoich danych, to właśnie wersja 4 nie mówi nikomu niczego. Dwie specjalne wartości pochodzące ze standardu nie są wersjami, dlatego nie znajdziesz ich w opcjach pola Wersja, ale możesz je stąd skopiować: nil UUID to 00000000-0000-0000-0000-000000000000, a max UUID to ffffffff-ffff-ffff-ffff-ffffffffffff. Wszystko na tej stronie jest zgodne z RFC 9562, czyli specyfikacją, która w 2024 roku zastąpiła RFC 4122, co oznacza, że dane wyjściowe zostaną zaakceptowane przez każdą bibliotekę, bazę danych czy interfejs API obsługujący UUID. W ramach tych granic gwarancja jest solidna: każdy identyfikator jest budowany zgodnie ze standardem, z wykorzystaniem kryptograficznie bezpiecznej losowości, na Twojej własnej maszynie, i nikt inny nigdy go nie widzi.