Szüksége van egy olyan azonosítóra, amely nem fog ütközni egy olyannal, amit valaki más készített egy olyan gépen, amiről még soha nem hallott, anélkül, hogy bárkitől engedélyt kérne? Pontosan ez az a feladat, amit egy UUID ellát. Ez egy 128 bites szám, amelyet 36 karakterként írunk le az ismerős 8-4-4-4-12 mintázatban, és a teljes felépítése arra irányul, hogy soha ne legyen belőle két egyforma, még akkor sem, ha semmi sem hangolja össze, hogy ki melyiket kapja. Ez az ingyenes generátor a böngészőjében hozza létre őket: válassza ki a verziót a „Verzió” menüpontban, adja meg, hányra van szüksége a „Darabszám” mezőben, majd nyomja meg a „Generálás” gombot. Az oldal egyetlen v4-gyel nyílik meg, amire a legtöbb projektnek szüksége van, így az első azonosító csupán egyetlen kattintásnyira van.
Minden azonosítót a böngészője épít fel a Web Crypto API-n keresztül. A 4-es verzió a crypto.randomUUID() függvényt használja, ahol a böngésző biztosítja azt, máskülönben pedig a crypto.getRandomValues() függvényt — egy kriptográfiailag erős véletlenszám-forrást egy JavaScript pszeudovéletlen függvény (mint például a Math.random()) helyett. A 7-es verzió egy 48 bites milliszekundum pontosságú időbélyeget helyez az elejére, majd egy 12 bites számlálót, amely ugyanazon milliszekundumon belül növekszik, majd 62 véletlenszerű bitet, és pontosan ez a rendezési módszer, amelyet az RFC 9562 leír; ez a számláló az oka annak, hogy egy ezer darabos csomag sorrendben érkezik, nem pedig összekeverve. Az 1-es verzió egy időbélyeget kombinál egy véletlenszerű csomópont-azonosítóval, amelynél a multicast bit be van állítva, így soha nem tartalmazza a hálózati kártya címét úgy, ahogy azt az eredeti 1990-es évekbeli implementációk tették. A 3-as és 5-ös verzió egyáltalán nem véletlenszerű: ezek egy névteret hashelnek össze egy névvel, az MD5 és az SHA-1 használatával, és ez a hashelés szintén a saját eszközén történik. Semmit sem küldünk szerverre, semmit sem naplózunk, és miután az oldal betöltődött, kapcsolat nélkül is működik tovább.
A „Verzió” az a mező, ami minden másról dönt. A 4-es verzió 122 véletlenszerű bitből áll mindenféle struktúra nélkül — ez az alapértelmezett, és a helyes válasz olyankor, amikor egy azonosítónak csupán egyedinek kell lennie. A 7-es verzió megtartja a 62 véletlenszerű bitet, de a létrehozási idővel kezdődik, így egy ilyen halmaz a létrehozásuk sorrendjében rendezhető; ezért érdemes ezt a verziót választani, ha az azonosítóból adatbázis-kulcs lesz. Az 1-es verzió az eredeti időalapú séma, amit azon rendszerek kedvéért tartottunk meg, amelyek még mindig ezt kérik. A 3-as és 5-ös verzió a furcsa páros: ezek determinisztikusak, ami azt jelenti, hogy ugyanazok a bemenetek mindig ugyanazt az azonosítót eredményezik, és két extra mezőt igényelnek — a „Névtér” mezőt, amely a DNS, URL, OID és X.500 szabványos terek egyike, vagy egy saját „Egyéni” tér („Egyéni névtér (UUID)”), valamint a „Név” mezőt, amely a vizsgált karakterlánc. Adja meg az 5-ös verziónak az URL névteret és a https://example.com/a címet, és ugyanazt az UUID-t kapja ma, holnap, és bárki más gépén is. Emiatt a „Darabszám” eltűnik, amikor a v3 vagy v5 van kiválasztva: egy determinisztikus érték ezer példánya egyszerűen csak egy determinisztikus érték ezer példánya lenne. Minden más verzió esetében a „Darabszám” 1-től 1000-ig terjed.
Négy kapcsoló megváltoztatja a kimenet alakját anélkül, hogy megváltoztatná az alatta lévő 128 bitet. A „Nagybetűs” verzálisokkal írja ki a hexadecimális számjegyeket, a „Kötőjelek nélkül” a kompakt 32 karakteres formát adja, amit néhány oszlop és fájlnév preferál, a „Kapcsos zárójelek” pedig { } jelek közé burkolja az értéket — ez az a forma, amit a Windows és a .NET világ GUID-nak hív. A „Speciális beállítások” alatt található urn:uuid: hozzáadja azt a prefixet, ami formális URN-né teszi; bekapcsolása esetén kikapcsolja a „Kapcsos zárójelek” és a „Kötőjelek nélkül” opciókat, mivel a szabvány pontosan egy URN formát engedélyez, és az a kötőjeles kanonikus forma. A „Másolási formátum” dönti el, hogyan legyen összekötve a csomag a kimásoláskor: soronként egy, vesszővel elválasztva, vagy minden érték idézőjelben egy záró vesszővel, ami egyenesen beilleszthető egy tömbbe a kódban. Az eredmény alatt egy sor található, amely a véletlenszerűséget jelenti bitben — 122 a v4-nél, 62 a v7-nél —, és a v7 esetében a csomag első azonosítójába kódolt időbélyeget mutatja, így az értéken belüli idő látható, nem pedig csak sejtett. Az „Összes másolása” és a „Mentés fájlba” egyaránt tiszteletben tartja a „Másolási formátum” beállítását. Az „Előzmények” a böngészőjében tartja az utolsó 10 csomagját: kattintson az egyikre, hogy visszahozza, másoljon vagy töröljön egyetlen bejegyzést, vagy törölje az egészet. A „Törlés” kiüríti az eredményt, miközben érintetlenül hagyja a beállításokat, és 50 azonosító után a lista ötven sor helyett egyetlen görgethető blokká válik.
A legfontosabb dolog ezen az oldalon a v4 és a v7 közötti különbség elsődleges kulcsként, és ez nem ízlés dolga. Az adatbázis indexek rendezett sorrendben tartott fák, és az, hogy egy új kulcs hol landol ebben a sorrendben, eldönti, mennyi munkába kerül a beszúrás. Egy v4 kulcs véletlenszerű, így az egymást követő beszúrások az index egymáshoz nem kapcsolódó sarkaiban landolnak: a megtelt oldalak felhasadnak, a fa azon részei, amelyeket az adatbázis a memóriában tart, ritkán azok a részek, amelyekre a következő beszúrásnak szüksége van, és az index végül nagyobb és töredezettebb lesz, mint amit a sorok indokolnának. Egy v7 kulcs az aktuális milliszekundummal kezdődik, így az egymást követő beszúrások egymás mellett landolnak a fa jobb szélén, ami az automatikusan növekvő egész számok által produkált minta, és az a minta, amely köré az indexstruktúrákat építették. Ez az egész kompromisszum lényege: a v7 egy szekvenciális kulcs beszúrási viselkedését nyújtja, miközben megtartja azt a tulajdonságot, amiért eleve az UUID-kat választotta, vagyis hogy bárki verhet egyet anélkül, hogy megkérdezne egy szervert. Ennek az az ára, hogy a létrehozás ideje immár olvashatóvá válik az azonosítón belül, és az, hogy ez számít-e, az ön adataira vonatkozó kérdés, nem pedig a formátumé.
Semmi sem ellenőrzi soha egy UUID egyediségét; a mérete a garancia. Nincs regiszter, nincs szerverhez fordulás, nincs keresés — egy generátor előállít egy számot és átadja, és az ok, amiért kettő nem ütközik, egyszerűen az, hogy 2^122 lehetséges v4 érték van, körülbelül 5,3 szextillió. A születésnap-paradoxon az őszinte módja ennek a méretezésére: nagyjából 2,7 trillió azonosítóra lenne szükség, mielőtt 50%-os esély lenne arra, hogy bármelyik kettő egyezzen, ami egymilliárd új UUID minden másodpercben 86 éven keresztül. Érdemes pontosan tudni, hogy mit ígér és mit nem. Ez egy statisztikai garancia, nem aritmetikai, és csak addig érvényes, amíg a mögöttes véletlenszerűség valódi — egy rosszul inicializált generátor, vagy egy virtuális gép, amelyet az entrópia-készletével együtt klónoztak, úgy töri meg, hogy a formátum nem tudja észlelni. A 7-es verzió tovább szűkíti a kérdést: egyetlen milliszekundumon belül egy generátor egyáltalán nem tudja ismételni önmagát, mert a számláló növekszik ahelyett, hogy kockát vetne, és a független generátorok között a 62 véletlenszerű bit végzi a munkát.
Egy UUID egy azonosító, nem egy jelszó. A 4-es verzió megjósolhatatlan, és ez kísértésbe ejti az embereket, hogy titokként kezeljék — egy jelszó-visszaállító linkként, egy kitalálhatatlan URL-ként, egy munkamenet-tokenként vagy egy API kulcsként. A megjósolhatatlanság valós, de a titoktartás annak a tulajdonsága, ahogyan egy értékkel bánnak, és az azonosítókat tervezésükből fakadóan hanyagul kezelik: URL-ekben ülnek, amelyek a böngészési előzményekben, a szervernaplókban, a referer fejlécekben és az analitikákban kötnek ki, valamint chatüzenetekbe illesztik őket. A többi verzió még rosszabb jelölt. Az 1-es és a 7-es verzió is kódolja a létrehozás pillanatát, így aki rendelkezik egy ilyennel, nagyjából tudja, mikor készült, és leszűkítheti a vele együtt készített dolgok környezetét. A 3-as és 5-ös verzió szándékosan determinisztikus: egy e-mail cím v5 UUID-ja nem egy hashelt titok, hanem egy olyan érték, amelyet bárki kiszámíthat egy másodperc alatt, ha ismeri ugyanazt a címet. Használja az UUID-t egy dolog elnevezésére. Használjon jelszógenerátort, vagy egy titkokhoz épített könyvtárból származó tokent olyankor, amikor az értéknek ismeretlennek kell maradnia.
Miért válassza ezt az UUID generátort?
- Kizárólag böngészőn belüli generálás: az azonosítók a saját eszközén készülnek, és soha nem küldjük sehova
- Web Crypto API véletlenszerűség: kriptografikusan biztonságos, nem pedig Math.random()
- Öt verzió egy helyen: v1, v3, v4, v5 és v7, anélkül, hogy eszközt váltana
- Valódi rendezett v7: egy számláló a milliszekundumon belül, ahogyan azt az RFC 9562 leírja
- Determinisztikus v3 és v5 a négy szabványos névtérrel vagy a sajátjával
- Akár 1000 darab egyszerre, ötven után kompakt, görgethető listával
- Minden gyakori forma: kötőjeles, csupasz, nagybetűs, kapcsos zárójeles vagy urn:uuid: URN
- Másolás sorként, vesszőkkel vagy idézőjelek között, ami egyenesen kódba illeszthető
- Korlátlan és ingyenes: nincs regisztráció, nincsenek használati korlátok, semmi sincs a szervereinken
Az UUID-k bárhol felbukkannak, ahol valamit meg kell nevezni, mielőtt bármi megerősíthetné, hogy a név szabad. Az alkalmazás kódja megüti őket a beillesztendő sorokhoz, így az objektum már azelőtt kap egy identitást, hogy elérte volna az adatbázist, és egy kliens hivatkozhat rá, amíg az írás még folyamatban van. Az elosztott rendszerek még jobban támaszkodnak rájuk: több szolgáltatás, amely egyetlen táblába ír, egy offline mobil kliens, amely a repülőgépen hoz létre rekordokat, egy üzenetsor, amelynek fel kell ismernie a már feldolgozott üzenetet — ezek egyike sem várhat a sorára egy megosztott számlálónál. Az 5-ös verzió egy másik igényt elégít ki, ami egy stabil azonosító egy már meglévő dologból levezetve: ugyanaz a dokumentum, ugyanaz az URL vagy ugyanaz a fiók mindig ugyanarra az UUID-ra mutat, így egy importálás kétszer is lefuthat anélkül, hogy bármit is duplikálna. Máshol egyszerűen a rendszer által megkövetelt formátumot jelentik — egy naplókba és nyomkövetésekbe fűzött korrelációs azonosító, egy fájlnév, amely nem fog ütközni, amikor ezer felhasználó feltöltése egyetlen tárolóba érkezik, egy Windows rendszerleíró kulcs, vagy egy tesztadat, amelynek úgy kell kinéznie, mint a valós adat.
Néhány őszinte korlátot érdemes ismerni. Egy csomag egy verziót jelent: a „Verzió” mezőben lévő érték mindenre vonatkozik, ami benne van, így egy sor v4 és egy sor v7 két külön csomagot alkot. Ez egy generátor, nem egy vizsgáló — egy UUID beillesztése a verziójának vagy az időbélyegének visszaolvasásához nem olyasmi, amit ez az oldal csinál. A „Mentés fájlba” opció egyszerű szöveges fájlt ír CSV vagy JSON helyett. A 7-es verzió nyíltan felfedi, mikor hozták létre, milliszekundum pontossággal, ami egy valós kompromisszum, nem pedig egy hiba, és az 1-es verzió is ugyanígy kiszivárogtatja az időt; ha ez problémát jelent az adatai számára, akkor a 4-es verzió az a verzió, amely senkinek sem mond semmit. A szabványból származó két speciális érték nem verzió, és így nem is opció a „Verzió” alatt, de innen kimásolhatja őket: a nil UUID, 00000000-0000-0000-0000-000000000000, és a max UUID, ffffffff-ffff-ffff-ffff-ffffffffffff. Ezen az oldalon minden követi az RFC 9562-t, a specifikációt, amely 2024-ben felváltotta az RFC 4122-t, így a kimenetet bármelyik könyvtár, adatbázis vagy API elfogadja, amely egyáltalán kezeli az UUID-kat. Ezeken a korlátokon belül a garancia erős: minden azonosító a szabvány szerint épül fel, kriptografikusan biztonságos véletlenszerűségből, az ön saját gépén, és soha senki más nem látja.