Keni nevojë për një identifikues që nuk do të përplaset me një tjetër të krijuar nga dikush tjetër, në një makineri për të cilën nuk keni dëgjuar kurrë, pa i kërkuar leje askujt? Kjo është detyra që kryen një UUID. Është një numër 128-bit, i shkruar si 36 karaktere në modelin e njohur 8-4-4-4-12, dhe i gjithë dizajni i tij qëndron tek fakti se dy të tillë nuk do të jenë kurrë njësoj edhe pse asgjë nuk e koordinon se kush merr cilin. Ky gjenerues falas i krijon ato në shfletuesin tuaj: zgjidhni një version tek „Versioni“, tregoni se sa ju duhen tek „Numri“, dhe shtypni „Gjenero“. Faqja hapet me një v4 të vetëm, versionin që kërkon shumica e projekteve, kështu që një identifikues i parë është vetëm një klikim larg.
Çdo identifikues ndërtohet nga shfletuesi juaj nëpërmjet Web Crypto API. Versioni 4 përdor crypto.randomUUID() aty ku shfletuesi e ofron atë dhe crypto.getRandomValues() në të kundërt — një burim kriptografikisht i fortë rastësie në vend të një funksioni pseudo-të-rastësishëm të JavaScript si Math.random(). Versioni 7 vendos një vulë kohore 48-bit në milisekonda në fillim, pastaj një numërues 12-bit që rritet brenda së njëjtës milisekondë, pastaj 62 bit të rastësishëm, e cila është metoda e renditjes e përshkruar në RFC 9562; ai numërues është arsyeja pse një grup prej një mijë copësh del në rregull dhe jo i përzier. Versioni 1 kombinon një vulë kohore me një identifikues nyjeje të rastësishëm që ka të vendosur bitin multicast, kështu që asnjëherë nuk mbart adresën e kartës suaj të rrjetit siç bënin zbatimet origjinale të viteve 1990. Versionet 3 dhe 5 nuk janë aspak të rastësishëm: ato bashkojnë përmes një funksioni hash një hapësirë emri së bashku me një emër, duke përdorur përkatësisht MD5 dhe SHA-1, dhe ai bashkim ndodh gjithashtu në pajisjen tuaj. Asgjë nuk dërgohet në një server, asgjë nuk regjistrohet, dhe sapo faqja të jetë ngarkuar ajo vazhdon të funksionojë edhe me lidhjen e fikur.
„Versioni“ është fusha që vendos gjithçka tjetër. Versioni 4 është 122 bit të rastësishëm dhe asnjë strukturë — opsioni i parazgjedhur dhe përgjigjja e saktë kur një identifikues thjesht duhet të jetë unik. Versioni 7 ruan 62 bit të rastësishëm por fillon me kohën kur u krijua, kështu që një grup i tyre renditet në radhën që janë bërë; prandaj është versioni që duhet zgjedhur kur identifikuesi do të bëhet një çelës për bazën e të dhënave. Versioni 1 është skema origjinale e bazuar në kohë, e mbajtur këtu për sistemet që ende e kërkojnë. Versionet 3 dhe 5 janë dyshja e çuditshme: ato janë deterministe, që do të thotë se të njëjtat të dhëna hyrëse japin gjithmonë të njëjtin identifikues, dhe kërkojnë dy fusha shtesë — „Hapësira e emrit“, e cila është një nga hapësirat standarde DNS, URL, OID dhe X.500 ose një e personalizuar nga ana juaj, dhe „Emri“, vargu që po identifikohet. Jepini v5 hapësirën e emrit URL dhe https://example.com/a dhe ju do të merrni të njëjtin UUID sot, nesër dhe në makinën e dikujt tjetër. Për këtë arsye, „Numri“ zhduket kur zgjidhet v3 ose v5: një mijë kopje të një vlere deterministe do të ishin një mijë kopje të së njëjtës vlerë. Për çdo version tjetër „Numri“ shkon nga 1 deri në 1000.
Katër çelësa ndryshojnë formën e rezultatit pa ndryshuar 128 bitët në bazë. „Shkronja të mëdha“ shtyp shifrat heksadecimale me kapitale, „Pa viza lidhëse“ ofron formën kompakte me 32 karaktere të cilën e preferojnë disa kolona dhe emra skedarësh, ndërsa „Kllapa gjarpërore“ e mbështjell vlerën në { } — forma të cilën Windows dhe bota e .NET e quajnë GUID. Nën „Opsione të Përparuara“, urn:uuid: i shton prefiksin që e bën atë një URN formal; ky çelës çaktivizon „Kllapa gjarpërore“ dhe „Pa viza lidhëse“ për aq kohë sa është i ndezur, sepse standardi lejon saktësisht vetëm një formë URN, dhe ajo është forma kanonike me viza lidhëse. „Formati i kopjimit“ vendos se si bashkohet një grup kur e merrni atë: një për rresht, të ndarë me presje, ose secila vlerë në thonjëza me një presje në fund, gjë që mund të ngjitet direkt në një array në kod. Nën rezultatin gjendet një rresht që raporton rastësinë në bit — 122 për v4, 62 për v7 — dhe, për v7, vulën kohore të koduar në identifikuesin e parë të grupit, në mënyrë që koha brenda vlerës të jetë e dukshme dhe jo e nënkuptuar. Si „Kopjo të gjitha“ ashtu edhe „Ruaj në skedar“ e respektojnë formatin e kopjimit të zgjedhur. „Historiku“ mban 10 grupet tuaja të fundit në vetë shfletuesin tuaj: klikoni njërën për ta rikthyer atë, kopjoni ose fshini një hyrje të vetme, ose pastroni të gjithën. „Pastro“ boshatis rezultatin dhe i lë të paprekura parametrat tuaja, dhe pas 50 identifikuesish lista bëhet një bllok i vetëm i lëvizshëm në vend të pesëdhjetë rreshtave.
Gjëja me më shumë pasoja në këtë faqe është ndryshimi midis v4 dhe v7 si një çelës primar (primary key), dhe nuk është një çështje shijeje. Indekset e bazave të të dhënave janë pemë të mbajtura në renditje të renditur, dhe ku një çelës i ri bie në atë renditje, vendos se sa punë do të kushtojë futja. Një çelës v4 është i rastësishëm, kështu që futjet e njëpasnjëshme bien në qoshe të palidhura të indeksit: faqet që ishin të plota ndahen (page split), pjesët e pemës që baza e të dhënave i mban në memorje janë rrallë pjesët që i duhen futjes së radhës, dhe indeksi përfundon të jetë më i madh dhe më i fragmentuar sesa arsyetojnë rreshtat ku ai drejtohet. Një çelës v7 fillon me milisekondën aktuale, kështu që futjet e njëpasnjëshme bien pranë njëra-tjetrës në skajin e djathtë të pemës, i cili është modeli që prodhon një numër i plotë me rritje automatike dhe modeli rreth të cilit u ndërtuan strukturat e indekseve. Ky është i gjithë kompromisi: v7 ju blen sjelljen e futjes së një çelësi vijues ndërkohë që mban vetinë e cila ju bëri të zgjidhni UUID në radhë të parë, domethënë faktin që secili mund të stampojë një pa pyetur një server. Ajo që kushton është se koha e krijimit tani është e lexueshme brenda identifikuesit, dhe nëse kjo ka rëndësi apo jo, është një pyetje rreth të dhënave tuaja, jo rreth formatit.
Asnjë gjë nuk e kontrollon ndonjëherë një UUID për unikalitet; madhësia e tij është garancia. Nuk ka asnjë regjistër, asnjë udhëtim vajtje-ardhje në një server, asnjë kërkim — një gjenerues prodhon një numër dhe e dorëzon atë, dhe arsyeja pse dy prej tyre nuk përplasen është thjesht se ekzistojnë 2^122 vlera të mundshme v4, rreth 5,3 sekstilionë. Problemi i ditëlindjes (birthday problem) është mënyra e ndershme për ta vlerësuar këtë: ju do t'ju duheshin rreth 2,7 trilionë identifikues para se të kishte një shans të barabartë që cilido prej dy prej tyre të përputhej, gjë që do të thotë një miliard UUID të reja çdo sekondë për 86 vjet. Vlen të jemi të saktë për atë që kjo premton dhe nuk premton. Kjo është një garanci statistikore, jo një garanci aritmetike, dhe ajo vlen vetëm për sa kohë që rastësia poshtë saj është e vërtetë — një gjenerues me pikënisje të keqe, ose një makinë virtuale e klonuar së bashku me grupin e saj të entropisë, e thyen atë në një mënyrë që formati nuk e zbulon dot. Versioni 7 e ngushton edhe më tej pyetjen: brenda një milisekonde të vetme një gjenerues nuk mund të përsërisë veten aspak, sepse numëruesi rritet në vend që të hedhë zaret, ndërsa midis gjeneruesve të pavarur puna bëhet nga 62 bitët e rastësishëm.
Një UUID është një identifikues, jo një fjalëkalim. Versioni 4 është i paparashikueshëm, dhe kjo i tundon njerëzit ta trajtojnë atë si një sekret — një lidhje për të rivendosur fjalëkalimin, një URL të pagjetshme, një token seance, një çelës API. Paparashikueshmëria është e vërtetë, por fshehtësia është një veti se si trajtohet një vlerë, dhe identifikuesit trajtohen me pakujdesi me vetëdije: ata qëndrojnë në URL, të cilat përfundojnë në historikun e shfletuesit, në regjistrat e serverit, në titujt e referrer dhe në analitikë, si dhe ngjiten në mesazhe bisedash. Versionet e tjera janë kandidatë edhe më të këqij. Versioni 1 dhe versioni 7 të dyja kodojnë momentin e krijimit, kështu që kushdo që mban një të tillë, e di afërsisht se kur u krijua dhe mund të ngushtojë rrethinën e gjithçkaje tjetër të krijuar së bashku me të. Versionet 3 dhe 5 janë të qëllimshme deterministe: një UUID v5 e një adrese emaili nuk është një sekret i konvertuar, por është një vlerë që çdokush me të njëjtën adresë mund ta llogarisë në një sekondë. Përdorni një UUID për të emërtuar një gjë. Përdorni një gjenerues fjalëkalimesh, ose një token nga një librari e ndërtuar për sekrete, kur vlera duhet të mbetet e panjohur.
Pse të zgjidhni këtë gjenerues UUID?
- Gjenerim vetëm në shfletues: identifikuesit bëhen në pajisjen tuaj dhe nuk dërgohen asnjëherë askund
- Rastësi përmes Web Crypto API: kriptografikisht e sigurt, jo Math.random()
- Pesë versione në një vend: v1, v3, v4, v5 dhe v7, pa qenë nevoja të ndërroni mjete
- V7 e renditur vërtetë: një numërues brenda milisekondës, siç e përshkruan RFC 9562
- V3 dhe v5 deterministe me katër hapësira standarde emrash ose me tuajën
- Deri në 1000 njëkohësisht, me një listë kompakte të lëvizshme kur tejkalojnë pesëdhjetë
- Çdo formë e zakonshme: me viza, e pastër, me kapitale, me kllapa ose si një URN urn:uuid:
- Kopjimi si rreshta, presje ose vlera në thonjëza që ngjiten direkt në kod
- E pakufizuar dhe falas: pa regjistrim, pa limite përdorimi, asgjë në serverët tanë
UUID-të shfaqen kudo ku diçka duhet të emërtohet përpara se dikush të mund të konfirmojë që emri është i lirë. Kodi i aplikacionit i formon ato për rreshtat që do të futë, kështu që objekti të ketë një identitet përpara se të ketë arritur ndonjëherë në bazën e të dhënave dhe një klient të mund t'i referohet atij ndërkohë që shkrimi është ende në proces. Sistemet e shpërndara mbështeten edhe më fort tek ato: disa shërbime që shkruajnë në të njëjtën tabelë, një klient mobil i cili punon offline ndërkohë që krijon regjistrime në një avion, një radhë (queue) që duhet të njohë mesazhin që e ka përpunuar tashmë — asnjëri nga këto nuk mund të presë radhën tek një numërues i përbashkët. Versioni 5 mbulon një nevojë tjetër, e cila është një identifikues i qëndrueshëm që rrjedh nga diçka që tashmë e keni: i njëjti dokument, e njëjta URL ose e njëjta llogari hartohen gjithmonë me të njëjtin UUID, kështu që një import mund të ekzekutohet dy herë pa dyfishuar asgjë. Diku tjetër ato janë thjesht formati që një sistem e kërkon me ngulm — një identifikues korelativ i kaluar përmes regjistrave dhe gjurmimeve, një emër skedari që nuk do të përplaset kur ngarkimet nga një mijë përdorues bien në të njëjtin vend, një çelës regjistri në Windows, një konfigurim testimi (test fixture) që duhet të duket ashtu si të dhënat e vërteta.
Vlen të njihen disa kufizime të ndershme. Një grup është një version: vlera në „Versioni“ zbatohet për çdo gjë që gjendet në të, kështu që një numër njësish v4 dhe një numër njësish v7 janë dy grupe. Ky është një gjenerues, jo një inspektor — ngjitja e një UUID për të rilexuar versionin e tij ose vulën e tij kohore nuk është diçka që kjo faqe e bën. „Ruaj në skedar“ shkruan një skedar teksti të thjeshtë në vend të CSV apo JSON. Versioni 7 zbulon hapur kohën e krijimit, me saktësi deri në milisekondë, dhe ky është një kompromis i vërtetë e jo një e metë, dhe po kështu e zbulon kohën edhe versioni 1; nëse kjo është problem për të dhënat tuaja, versioni 4 është versioni që nuk i tregon askujt asgjë. Dy vlera të veçanta nga standardi nuk janë versione dhe rrjedhimisht nuk janë opsione në „Versioni“, por mund t'i kopjoni nga këtu: UUID zero (nil), 00000000-0000-0000-0000-000000000000, dhe UUID maksimale (max), ffffffff-ffff-ffff-ffff-ffffffffffff. Çdo gjë në këtë faqe ndjek RFC 9562, specifikimin që zëvendësoi RFC 4122 në vitin 2024, kështu që dalja pranohet nga çdo librari, bazë të dhënash apo API që manipulon fare UUID-të. Brenda këtyre kufijve garancia është e fortë: çdo identifikues ndërtohet në standard, nga një rastësi kriptografikisht e sigurt, në pajisjen tuaj, dhe asnjë tjetër nuk e sheh atë kurrë.