Potrebujete identifikator, ki ne bo v navzkrižju s katerim koli drugim, ki ga je ustvaril nekdo drug na napravi, za katero niste še nikoli slišali, in to brez da bi koga prosili za dovoljenje? To je naloga, ki jo opravlja UUID. Je 128-bitno število, zapisano kot 36 znakov v znanem vzorcu 8-4-4-4-12, in njegova celotna zasnova sloni na dejstvu, da si dva nikoli ne bosta enaka, čeprav nič ne usklajuje, kdo dobi katerega. Ta brezplačni generator jih ustvarja v vašem brskalniku: izberite različico v polju „Različica“, označite, koliko jih potrebujete, v polju „Število“, in pritisnite „Generiraj“. Stran se odpre na enem v4, kar je različica, ki jo želi večina projektov, zato je prvi identifikator oddaljen le en klik.
Vsak identifikator vaš brskalnik zgradi s pomočjo Web Crypto API. Različica 4 uporablja crypto.randomUUID() tam, kjer brskalnik to omogoča, sicer pa crypto.getRandomValues() — kriptografsko močan vir naključnosti in ne zgolj psevdonaključne funkcije JavaScripta, kot je Math.random(). Različica 7 na začetek postavi 48-bitni časovni žig v milisekundah, nato 12-bitni števec, ki se znotraj iste milisekunde povečuje, nato pa 62 naključnih bitov, kar predstavlja metodo razvrščanja po RFC 9562; zaradi tega števca se serija tisočih izpiše po vrsti in ne premešano. Različica 1 združuje časovni žig z naključnim identifikatorjem vozlišča, ki ima nastavljen bit za večsmerno oddajanje (multicast), zato nikoli ne nosi naslova vaše mrežne kartice, kot so to počele prvotne implementacije iz 90-ih. Različici 3 in 5 sploh nista naključni: združita imenski prostor z imenom z uporabo MD5 oz. SHA-1, pri čemer ta izračun prav tako poteka na vaši napravi. Nič se ne pošlje na strežnik, nič se ne beleži v dnevnike in ko je stran naložena, deluje tudi ob prekinjeni povezavi.
„Različica“ je polje, ki odloča o vsem ostalem. Različica 4 je 122 naključnih bitov brez kakršnekoli strukture — privzeta možnost in pravi odgovor, ko mora identifikator zgolj biti edinstven. Različica 7 ohranja 62 naključnih bitov, a se začne s časom nastanka, zato se nabor takih identifikatorjev samodejno razvrsti po vrstnem redu izdelave; to je različica, po kateri posežete, ko bo identifikator postal ključ v podatkovni bazi. Različica 1 je izvirna shema, ki temelji na času, tukaj pa je obdržana za sisteme, ki jo še vedno zahtevajo. Različici 3 in 5 sta poseben par: sta deterministični, kar pomeni, da enaki vhodni podatki vedno ustvarijo isti identifikator, in zahtevata dve dodatni polji — „Imenski prostor“, ki je eden izmed standardnih prostorov DNS, URL, OID in X.500 ali vaš lastni „Imenski prostor po meri (UUID)“, ter „Ime“, ki je sam identificiran niz. Podajte različici v5 imenski prostor URL in https://example.com/a ter prejeli boste povsem isti UUID danes, jutri in na računalniku nekoga drugega. Zaradi tega polje „Število“ izgine, ko izberete v3 ali v5: tisoč kopij deterministične vrednosti bi pomenilo le tisoč kopij ene in iste vrednosti. Za vsako drugo različico se „Število“ razteza od 1 do 1000.
Štiri stikala spreminjajo obliko izpisa, ne da bi ob tem spremenila 128 bitov v ozadju. „Velike črke“ izpišejo heksadecimalne znake z verzalkami, „Brez vezajev“ poda kompaktno obliko iz 32 znakov, ki jo nekatere kolone in imena datotek raje uporabljajo, „Vitičasti oklepaji“ pa vrednost obdajo z { } — obliko, ki ji Windows in svet .NET pravita GUID. Pod zavihkom „Napredne možnosti“ stikalo urn:uuid: doda predpono, ki naredi identifikator za formalni URN; to izklopi „Vitičasti oklepaji“ in „Brez vezajev“, dokler je vklopljeno, saj standard dopušča točno eno obliko URN, in sicer kanonično obliko z vezaji. „Format kopiranja“ odloča o tem, kako je serija združena ob prenosu: po en na vrstico, ločeno z vejicami ali vsaka vrednost v narekovajih z vejico na koncu, kar lahko prilepite neposredno v polje v kodi. Pod rezultatom se nahaja vrstica, ki sporoča naključnost v bitih — 122 za v4, 62 za v7 — ter za v7 tudi časovni žig, kodiran v prvem identifikatorju iz serije, tako da je čas znotraj vrednosti viden namesto le nakazan. Oba gumba, „Kopiraj vse“ in „Shrani v datoteko“, upoštevata „Format kopiranja“. „Zgodovina“ obdrži zadnjih 10 serij v vašem brskalniku: kliknite na katero izmed njih, da jo prikličete nazaj, kopirajte ali izbrišite posamezen vnos oziroma počistite celotno zgodovino. Gumb „Počisti“ izprazni rezultat, vaše nastavitve pa ohrani nedotaknjene, pri čemer se nad 50 identifikatorji seznam spremeni v en drsljiv blok namesto petdesetih vrstic.
Najbolj pomembna stvar na tej strani je razlika med v4 in v7 pri uporabi kot primarni ključ v bazi (primary key), in to ni stvar okusa. Indeksi v podatkovnih bazah so drevesa, shranjena v določenem zaporedju, in od mesta, kamor nov ključ pristane v tem zaporedju, je odvisno, koliko dela bo to vstavljanje zahtevalo. Ključ v4 je naključen, zato zaporedna vstavljanja pristanejo v medsebojno nepovezanih kotičkih indeksa: strani (page split), ki so bile že polne, se cepijo, deli drevesa, ki jih podatkovna baza drži v pomnilniku, pa so le redko tisti, ki jih potrebuje naslednje vstavljanje, in indeks na koncu postane večji ter bolj razdrobljen, kot bi bilo za vrstice, na katere kaže, upravičeno. Ključ v7 se začne s trenutno milisekundo, zato zaporedna vstavljanja pristanejo skupaj na desnem robu drevesa, kar je natanko tisti vzorec, ki ga proizvede rastoče celo število, in tisti vzorec, okoli katerega so bile strukture indeksov zgrajene. V tem je ves kompromis: v7 vam kupi obnašanje vstavljanja sekvenčnega ključa, ob tem pa obdrži lastnost, zaradi katere ste sploh izbrali UUID, in to je dejstvo, da ga lahko vsak ustvari brez spraševanja strežnika. Cena za to je le ta, da je čas nastanka sedaj berljiv znotraj identifikatorja; ali je to sploh pomembno, pa je vprašanje za vaše podatke in ne za format.
Nič nikoli ne preveri edinstvenosti UUID-ja; njegovo jamstvo je njegova velikost. Ni nobenega registra, nobenega pošiljanja k strežniku, nobenega iskanja — generator preprosto ustvari število in ga vrne, razlog, da dva ne prideta v navzkrižje, pa je v tem, da obstaja kar 2^122 možnih vrednosti za različico 4, približno 5,3 sekstilijona. Paradoks rojstnega dne (birthday problem) je pošten način ocenjevanja: potrebovali bi približno 2,7 trilijona identifikatorjev, preden bi imeli enako možnost za eno samo ujemanje, kar pomeni ustvarjanje milijarde novih UUID-jev vsako sekundo v obdobju 86 let. Vredno je biti natančen glede tega, kaj to obljublja in kaj ne. Gre za statistično jamstvo, ne aritmetično, ki velja le ob pogoju, da je naključnost v ozadju resnična — slabo začetno stanje (seed) generatorja ali kloniran virtualni stroj skupaj z njegovim zalogovnikom entropije jamstvo poruši na način, ki ga sam format ne more zaznati. Različica 7 to vprašanje še dodatno zoži: znotraj ene same milisekunde se generator sploh ne more ponoviti, saj se števec le povečuje in ne meče kock, pri povsem neodvisnih generatorjih pa tistih 62 naključnih bitov zlahka opravi svoje delo.
UUID je identifikator in ne geslo. Različica 4 je nepredvidljiva in to ljudi pogosto zamika, da bi jo obravnavali kot skrivnost — kot povezavo za ponastavitev gesla, URL, ki ga ni mogoče uganiti, žeton za sejo, ključ za API. Nepredvidljivost je sicer resnična, a skrivnostnost je lastnost tega, kako se z neko vrednostjo ravna, identifikatorji pa so že v osnovi obravnavani malomarno: nahajajo se v URL-jih, ki končajo v zgodovini brskalnika, dnevnikih strežnika, v glavah 'referrer' in analitiki ter se pogosto prilepijo v sporočila. Ostale različice so še bistveno slabši kandidati za kaj takšnega. Različici 1 in 7 obe vkodirata trenutek nastanka, zato vsak, ki ju vidi, ve, približno kdaj sta nastali in lahko zoži okolico vseh ostalih elementov, ki so nastali skupaj z njima. Različici 3 in 5 sta namenoma deterministični: UUID v5 vašega elektronskega naslova ni kriptirana skrivnost, ampak vrednost, ki jo lahko v sekundi izračuna vsakdo z istim e-poštnim naslovom. UUID uporabite, da nekaj poimenujete. Če mora vrednost ostati neznana, uporabite generator gesel ali žeton iz knjižnice, ki je narejena posebej za skrivnosti.
Zakaj izbrati ta generator UUID?
- Generiranje samo v brskalniku: identifikatorji nastanejo na vaši napravi in se nikoli nikamor ne pošljejo
- Naključnost na osnovi Web Crypto API: kriptografsko varno in zanesljivo, brez funkcije Math.random()
- Pet različic na enem mestu: v1, v3, v4, v5 in v7, ne da bi za to zamenjali orodje
- Resnično urejen v7: vsebuje števec znotraj milisekunde, kot to določa RFC 9562
- Determinističen v3 in v5 s štirimi standardnimi imenskimi prostori ali celo z vašim lastnim
- Do 1000 naenkrat, s kompaktnim drsljivim seznamom nad petdeset vrednosti
- Vsaka običajna oblika: z vezaji, brez vsega, z velikimi črkami, v oklepajih ali pa kot URN urn:uuid:
- Kopirajte v vrsticah, s presledki ali narekovaji za neposredno vstavljanje v samo kodo
- Neomejeno in brezplačno: brez prijave, brez kakršnihkoli omejitev in brez sledi na našem strežniku
UUID-ji se pojavijo povsod, kjer je treba nekaj poimenovati preden sploh lahko potrdimo, da je to ime dejansko prosto. Aplikacijska koda jih kuje za tiste vrstice, ki jih namerava vstaviti, tako da dobi objekt svojo identiteto, še preden doseže podatkovno bazo, stranka pa se lahko nanj sklicuje, medtem ko to vpisovanje še traja. Distribuirani sistemi se nanje še bolj zanašajo: več storitev, ki hkrati zapisujejo v eno tabelo, odklopljen mobilni klient (offline), ki vnaša zapise nekje na letalu, čakalna vrsta, ki mora znati prepoznati točno tisto sporočilo, ki ga je že obdelala — prav nobeden od naštetih sistemov ne more čakati, da pride na vrsto pri nekem skupnem števcu. Različica 5 pokriva nekoliko drugačno potrebo, saj gre tu za stabilen identifikator, ki izhaja iz nečesa, kar v resnici že imate: povsem isti dokument, enak URL ali pač isti uporabniški račun, ki se v vsakem primeru preslika v povsem enak UUID, kar omogoča, da se lahko nek uvoz zažene tudi dvakrat, ne da bi ob tem karkoli podvojil. Ponekod drugje gre spet povsem preprosto za format, ki ga nek sistem strogo zahteva — korelacijski identifikator, ki je prepleten skozi dnevnike, preprosto ime datoteke, ki nikakor ne bo povzročilo konflikta ob nalaganju datotek tisočih različnih uporabnikov, ključ v registru za Windows in seveda kakšno testno ogrodje, ki se mora nujno obnašati in tudi videti povsem kot resnični podatki.
Poznavanje nekaj poštenih omejitev je vedno smiselno. Ena serija predstavlja eno različico: vrednost, določena v polju „Različica“, dejansko velja čisto za vse v njej, torej sta izvajanje za v4 in izvajanje za v7 preprosto dve seriji. To je zgolj generator, ne pa inšpektor — to pomeni, da vstavljanje nekega UUID-ja, da bi ugotovili njegovo različico ali prebrali časovni žig, ni funkcija te strani. Možnost „Shrani v datoteko“ zapiše le navadno besedilno datoteko in ne izvoza v CSV ali JSON. Različica 7 dokaj očitno in brez sramu razkriva, kdaj točno je bila ustvarjena (do milisekunde natančno), in to je povsem realen kompromis ter ne napaka, in na podoben način se časovno odpira tudi različica 1; če za vaše podatke to predstavlja kakršnokoli težavo, je različica 4 prava izbira, saj pač nikomur ne pove čisto ničesar. Dve posebni vrednosti, opredeljeni s standardom, nista dejanski različici in posledično tudi nista na voljo med možnostmi v polju „Različica“, a ju lahko brez težav kopirate neposredno od tukaj: nični UUID (nil UUID), 00000000-0000-0000-0000-000000000000, ter maksimalni UUID (max UUID), ffffffff-ffff-ffff-ffff-ffffffffffff. Vse na tej strani dosledno upošteva in sledi standardu RFC 9562 — točno tisti specifikaciji, ki je leta 2024 nadomestila RFC 4122 — kar pomeni, da je izpis brez težav sprejet v čisto vsaki knjižnici, na vsakem API-ju in podatkovni bazi za delo z UUID-ji. Znotraj the omejitev pa je to jamstvo nadvse trdno: popolnoma vsak identifikator je bil dejansko izdelan po strogem standardu in narejen z viri iz kriptografsko varne naključnosti v vašem brskalniku, kjer res noben drug nikoli nima dostopa.