Kailangan mo ba ng identifier na hindi sasalungat sa ginawa ng ibang tao, sa isang makinang hindi mo pa naririnig, nang hindi humihingi ng pahintulot kaninuman? Iyan ang trabahong ginagawa ng isang UUID. Ito ay isang 128-bit na numero, na nakasulat bilang 36 na karakter sa pamilyar na 8-4-4-4-12 pattern, at ang buong disenyo nito ay hindi kailanman magiging pareho ang dalawa sa mga ito kahit na walang nag-oorganisa kung sino ang makakakuha ng alin. Ang libreng generator na ito ay ginagawa ang mga ito sa iyong browser: pumili ng bersyon sa 'Bersyon', sabihin kung ilan ang kailangan mo sa 'Bilang ng mga pipiliin', at pindutin ang 'Bumuo ng resulta'. Magbubukas ang pahina na may isang v4, ang bersyong gusto ng karamihan sa mga proyekto, kaya ang unang identifier ay isang click na lang.
Ang bawat identifier ay binubuo ng iyong browser sa pamamagitan ng Web Crypto API. Ginagamit ng Bersyon 4 ang crypto.randomUUID() kung saan ibinibigay ito ng browser at crypto.getRandomValues() naman sa iba — isang cryptographically strong na pinagkukunan ng randomness sa halip na isang JavaScript pseudo-random function tulad ng Math.random(). Ang Bersyon 7 ay naglalagay ng 48-bit millisecond timestamp sa unahan, pagkatapos ay isang 12-bit counter na tumataas sa loob ng parehong millisecond, pagkatapos ay 62 random bits, na siyang paraan ng pag-order na inilalarawan sa RFC 9562; ang counter na iyon ang dahilan kung bakit ang isang batch ng isang libo ay lumalabas nang nakaayos kaysa sa naka-shuffle. Pinagsasama ng Bersyon 1 ang isang timestamp at isang random na node identifier na may naka-set na multicast bit, kaya hindi nito dinadala ang address ng iyong network card tulad ng ginawa ng mga orihinal na implementasyon noong 1990s. Ang mga Bersyon 3 at 5 ay hindi random: hina-hash nila ang isang namespace kasama ang isang pangalan, gamit ang MD5 at SHA-1 ayon sa pagkakabanggit, at ang pag-hash na iyon ay nangyayari din sa iyong device. Walang ipinapadala sa isang server, walang nalo-log, at sa sandaling mag-load ang pahina, patuloy itong gagana kahit patay ang koneksyon.
Ang 'Bersyon' ang field na nagpapasya sa lahat. Ang Bersyon 4 ay 122 random bits at walang istraktura — ang default, at ang tamang sagot kapag ang isang identifier ay kailangan lang maging natatangi. Pinapanatili ng Bersyon 7 ang 62 random bits ngunit nangunguna ang oras kung kailan ito ginawa, kaya ang isang set ng mga ito ay naaayos sa pagkakasunod-sunod ng paggawa sa kanila; iyon ang dahilan kung bakit ito ang bersyong dapat piliin kapag ang identifier ay magiging isang database key. Ang Bersyon 1 ay ang orihinal na time-based na pamamaraan, na pinanatili rito para sa mga system na humihingi pa rin nito. Ang mga Bersyon 3 at 5 ay ang naiibang pares: ang mga ito ay deterministic, ibig sabihin ang parehong mga input ay palaging gumagawa ng parehong identifier, at kumukuha sila ng dalawang karagdagang field — 'Namespace', na isa sa mga karaniwang space na DNS, URL, OID at X.500 o isang 'Custom' na sarili mo, at 'Pangalan', ang string na tinutukoy. I-feed sa v5 ang URL namespace at https://example.com/a at makukuha mo ang parehong UUID ngayon, bukas at sa makina ng iba. Dahil doon, nawawala ang 'Bilang ng mga pipiliin' kapag napili ang v3 o v5: ang isang libong kopya ng isang deterministic na halaga ay magiging isang libong kopya ng isang deterministic na halaga. Para sa bawat iba pang bersyon, ang 'Bilang ng mga pipiliin' ay mula 1 hanggang 1000.
Binabago ng apat na switch ang hugis ng output nang hindi binabago ang 128 bits sa ilalim. Ang 'Malalaking titik' ay nagpi-print ng hexadecimal digits bilang mga kapital, ang 'Walang gitling' ay nagbibigay ng siksik na 32-character form na mas gusto ng ilang column at pangalan ng file, at ang 'Mga kulot na panaklong' ay ibinabalot ang halaga sa { } — ang hugis na tinatawag ng Windows at ng mundo ng .NET na GUID. Sa ilalim ng 'Mga Advanced na Opsyon', idinadagdag ng urn:uuid: ang prefix na ginagawa itong isang pormal na URN; pino-turn off nito ang 'Mga kulot na panaklong' at 'Walang gitling' habang ito ay naka-on, dahil pinapayagan ng standard ang eksaktong isang URN form at ito ang canonical na may mga gitling. Ang 'Pormat ng pagkopya' ang nagpapasya kung paano pinagsasama ang isang batch kapag kinuha mo ito: isa bawat linya, pinaghihiwalay ng mga kuwit, o ang bawat halaga ay may mga panipi na may kasunod na kuwit, na idinidikit nang direkta sa isang array sa code. Sa ilalim ng resulta ay may isang linya na nag-uulat ng randomness sa bits — 122 para sa v4, 62 para sa v7 — at, para sa v7, ang timestamp na naka-encode sa unang identifier ng batch, kaya nakikita ang oras sa loob ng halaga kaysa ipinapahiwatig lamang. Parehong sinusunod ng 'Kopyahin Lahat' at 'I-save sa file' ang 'Pormat ng pagkopya'. Itinatago ng 'Kasaysayan' ang iyong huling 10 batch sa sarili mong browser: i-click ang isa para ibalik ito, kopyahin o tanggalin ang iisang entry, o i-clear ang lahat. Ina-empty ng 'I-clear' ang resulta at iniiwan ang iyong mga setting, at pagkalampas ng 50 identifiers, ang listahan ay nagiging isang scrollable block sa halip na limampung hilera.
Ang pinakamahalagang bagay sa pahinang ito ay ang pagkakaiba sa pagitan ng v4 at v7 bilang isang primary key, at hindi ito isyu ng panlasa. Ang mga database index ay mga B-tree na inilalagay sa sorted order, at kung saan mapupunta ang isang bagong key sa pagkakasunod-sunod na iyon ang nagpapasya kung gaano karaming trabaho ang magagastos sa insert. Ang isang v4 key ay random, kaya ang sunud-sunod na mga insert ay napupunta sa hindi magkakaugnay na sulok ng index: ang mga pahinang puno na ay naha-half split, ang mga bahagi ng puno na hawak ng database sa memorya ay bihirang mga bahaging kailangan ng susunod na insert, at ang index ay nagiging mas malaki at mas pira-piraso kaysa sa kung ano ang kailangan para sa mga row na itinuturo nito. Ang isang v7 key ay nagsisimula sa kasalukuyang millisecond, kaya ang mga sunud-sunod na insert ay magkakasamang napupunta sa kanang dulo ng puno, na siyang pattern na ginagawa ng isang auto-incrementing integer at ang pattern na pinagbatayan ng pagkakabuo ng mga index structure. Iyon ang kabuuang trade-off: binibigyan ka ng v7 ng insert behavior ng isang sequential key habang pinapanatili ang property na naging dahilan kaya mo pinili ang UUIDs sa simula pa lang, na kahit sino ay maaaring gumawa ng isa nang hindi nagtatanong sa isang server. Ang kapalit nito ay ang oras ng paggawa ay nababasa na ngayon sa loob ng identifier, at kung mahalaga ba iyon o hindi ay isang tanong tungkol sa iyong data, hindi tungkol sa format.
Walang kailanman na nagsusuri sa isang UUID para sa uniqueness; ang laki nito ang mismong garantiya. Walang registry, walang server round-trip, walang lookup — ang isang generator ay gumagawa ng isang numero at ibinibigay ito, at ang dahilan kung bakit hindi nagbabanggaan ang dalawa sa kanila ay dahil lamang sa mayroong 2^122 posibleng v4 na halaga, humigit-kumulang 5.3 undecillion (5.3 × 10^36). Ang birthday problem ay ang matapat na paraan upang sukatin iyon: kailangan mo ng humigit-kumulang 2.7 quintillion (2.7 × 10^18) na identifiers bago magkaroon ng pantay na pagkakataon na magtugma ang anumang dalawa sa kanila, na isang bilyong bagong UUID kada segundo sa loob ng 86 na taon. Sulit na maging tumpak tungkol sa kung ano ang ipinapangako at hindi ipinapangako niyan. Ito ay isang statistical guarantee, hindi isang arithmetic, at totoo lamang ito habang ang randomness sa ilalim nito ay tunay — ang isang generator na hindi maayos ang pagkakabuo, o isang virtual machine na nai-clone kasama ang entropy pool nito, ay sisira rito sa paraang hindi matutukoy ng format. Ang Bersyon 7 ay lalong nagpapaliit sa tanong: sa loob ng iisang millisecond ang isang generator ay hindi kailanman mauulit ang sarili nito, dahil ang counter ay tumataas sa halip na maging random, at sa iba't ibang mga independiyenteng generator ay ang 62 random bits ang gumagawa ng trabaho.
Ang UUID ay isang identifier, hindi isang password. Ang Bersyon 4 ay hindi mahuhulaan, at tinutukso nito ang mga tao na tratuhin ito bilang isang lihim — isang password-reset link, isang hindi mahuhulaan na URL, isang session token, isang API key. Ang pagiging unpredictable ay totoo, ngunit ang pagiging sikreto ay isang katangian kung paano pinangangasiwaan ang isang halaga, at ang mga identifier ay sadyang pinangangasiwaan nang walang pag-iingat: inilalagay ang mga ito sa mga URL, na napupunta sa history ng browser, server logs, referrer headers at analytics, at nai-paste sa mga chat message. Mas masamang kandidato pa ang ibang mga bersyon. Ang Bersyon 1 at bersyon 7 ay parehong nag-e-encode ng sandali ng paggawa, kaya sinumang may hawak nito ay alam halos kung kailan ito ginawa at mapapaliit ang saklaw ng lahat ng ginawa kasama nito. Sadyang deterministic ang mga Bersyon 3 at 5: ang isang v5 UUID ng isang email address ay hindi isang hashed secret, isa itong halaga na makukwenta sa isang segundo ng sinumang may parehong address. Gumamit ng UUID para pangalanan ang isang bagay. Gumamit ng password generator, o token mula sa isang library na ginawa para sa mga sikreto, kapag ang halaga ay dapat manatiling hindi alam.
Bakit dapat piliin ang UUID generator na ito?
- Pagbuo sa browser lamang: ang mga identifier ay ginagawa sa iyong device at hindi ipinapadala kahit saan
- Web Crypto API randomness: cryptographically secure, hindi Math.random()
- Limang bersyon sa isang lugar: v1, v3, v4, v5 at v7, nang hindi nagpapalit ng tools
- Tunay na naka-order na v7: isang counter sa loob ng millisecond, gaya ng inilalarawan sa RFC 9562
- Deterministic na v3 at v5 kasama ang apat na karaniwang namespace o ang sa iyo
- Hanggang 1000 sa isang pagkakataon, na may siksik na scrollable list pagkalampas sa limampu
- Bawat karaniwang hugis: may gitling, wala, malalaking titik, may panaklong o isang urn:uuid: URN
- Kopyahin bilang mga linya, kuwit o quoted values na direktang mai-paste sa code
- Walang limitasyon at libre: walang sign-up, walang limitasyon sa paggamit, wala sa aming mga server
Lumalabas ang UUIDs saanman kailangang pangalanan ang isang bagay bago makumpirma ng anuman na ang pangalan ay libre pa. Ang application code ay gumagawa ng mga ito para sa mga row na ilalagay nito, kaya ang bagay ay may pagkakakilanlan na bago pa man ito makarating sa database at maaari na itong i-reference ng isang client habang ang write ay kasalukuyang nangyayari. Mas umaasa rito ang distributed systems: ilang serbisyo na nagsusulat sa iisang table, isang offline mobile client na gumagawa ng mga record sa isang eroplano, isang queue na kailangang kilalanin ang mensaheng naproseso na nito — walang isa man sa mga iyon ang maaaring maghintay ng kanilang pagkakataon para sa isang shared counter. Sinasaklaw ng Bersyon 5 ang kakaibang pangangailangan, na isang matatag na identifier na nagmula sa isang bagay na mayroon ka na: ang parehong dokumento, ang parehong URL o ang parehong account ay palaging nagma-map sa parehong UUID, kaya ang isang import ay maaaring patakbuhin ng dalawang beses nang hindi dina-duplicate ang anuman. Sa ibang lugar, ang mga ito ay ang mismong format na hinihingi ng isang system — isang correlation identifier na dumadaan sa mga log at trace, isang filename na hindi magbabanggaan kapag napunta sa iisang bucket ang mga upload mula sa isang libong user, isang Windows registry key, isang test fixture na kailangang magmukhang totoong data.
Sulit ding malaman ang ilang matapat na limitasyon. Ang isang batch ay isang bersyon: ang halaga sa 'Bersyon' ay naaangkop sa lahat ng nasa loob nito, kaya ang isang run ng v4s at isang run ng v7s ay dalawang batch. Isa itong generator, hindi isang inspector — ang pag-paste ng UUID para basahin ang bersyon nito o ang timestamp nito ay hindi isang bagay na ginagawa ng pahinang ito. Nagsusulat ng plain text file ang 'I-save sa file' sa halip na CSV o JSON. Ang Bersyon 7 ay lantad na ibinubunyag kung kailan ito ginawa, hanggang sa millisecond, na isang totoong trade-off kaysa sa isang kapintasan, at pinalalabas ng bersyon 1 ang oras sa parehong paraan; kung problema iyon sa iyong data, ang bersyon 4 ay ang bersyon na walang sinasabi kaninuman. Dalawang espesyal na halaga mula sa standard ay hindi mga bersyon kaya hindi mga opsyon sa 'Bersyon', ngunit maaari mong kopyahin ang mga ito mula rito: ang nil UUID, 00000000-0000-0000-0000-000000000000, at ang max UUID, ffffffff-ffff-ffff-ffff-ffffffffffff. Ang lahat ng nasa pahinang ito ay sumusunod sa RFC 9562, ang detalye na pumalit sa RFC 4122 noong 2024, kaya ang output ay tinatanggap ng anumang library, database o API na humahawak ng UUIDs. Sa loob ng mga limitasyong iyon, ang garantiya ay matibay: ang bawat identifier ay binuo ayon sa standard, mula sa cryptographically secure na randomness, sa sarili mong makina, at walang ibang nakakakita nito kailanman.