ULID generaator

Genereerige ULID-sid veebis: 26-sümbolilised Crockford Base32 ID-d, millel on 48-bitine aeg ja 80 juhuslikku bitti.

Vorming
Genereeritud ID-d
Valmis. Genereerige ULID-sid otse oma brauseris.

Kuidas see ID on üles ehitatud

Struktuur
26 Crockford Base32 sümbolit: 10 ajasümbolit, millele järgneb 16 juhuslikku sümbolit.
Entroopia
80 juhuslikku bitti pärast 48-bitist millisekundite ajamärgist.
Aeg
Jah. Esimesed 10 sümbolit kodeerivad aega millisekundites ja leksikaalne järjekord järgib aega.
Kollisioonirisk
Juhuslikul lõpuosal on 80 bitti; risk sõltub peamiselt sellest, kui palju ID-sid luuakse täpselt samal millisekundil.
Näide
01M12BRPAPWY6HTZFTCA9C3N8B

Teie ID-d genereeritakse kohapeal tugeva brauseri juhuslikkuse abil. BroBroGo serverisse midagi ei saadeta.

KKK

Milleks ULID hea on?

ULID on kompaktne, URL-sõbralik ja ajaliselt sorditav lihttekstina, mis on kasulik logide, objektivõtmete ja loomisaja järgi sorditavate kirjete puhul.

Kas ULID on sama mis UUID v7?

Ei. Mõlemad sisaldavad millisekundite täpsusega aega, kuid ULID kasutab Crockford Base32 süsteemi ja 26 sümbolit, samas kui UUID v7 säilitab standardse UUID kuueteistkümnendkuju.

ULID-generaatori leht: Unikaalsed, ajaliselt sorteeritavad identifikaatorid

See leht võimaldab valida identifikaatorivorminguks ULID, määrata vajalike ID-de arvu (1 kuni 100) ja klõpsuga luua loendi ainulaadsetest, ajaliselt sorteeritavatest ULID-idest. Iga ID on 26-märgiline, tõstutundetu string, mida saab kopeerida üksikult või kõiki korraga. Erinevalt teistest sama tööriista vormingutest on ULID lühem kui UUID (26 märki vs 36) ja kasutab ainult Crockfordi base32 tähestikku – seega on need tõstutundetud ja ilma sidekriipsudeta. ULID-id on leksikograafiliselt sorteeritavad loomisaja järgi, sest esimesed 10 märki kodeerivad millisekunditäpsusega ajatemplit. Need on ka URL-ohutud ilma igasuguse escapinguta. Sellel lehel pole lüliteid suurtähtede ega sidekriipsude jaoks, sest ULID on olemuslikult tõstutundetu ja sidekriipsudeta. Juhuslik komponent hõlmab ülejäänud 16 märki (80 bitti) ja kogu aluseks olev väärtus on 128 bitti.

ULID-i sisemine struktuur: aeg ja juhuslikkus

ULID (Universally Unique Lexicographically Sortable Identifier) on 128-bitine identifikaator, mis jaguneb kaheks selgeks osaks:

  • Esimesed 10 märki (48 bitti): millisekunditäpsusega ajatempel alates Unixi epohhist (00:00:00 UTC, 1. jaanuar 1970). Kuna ajatempel on kodeeritud Crockfordi base32 abil, mahub 48 bitti 10 märgi sisse. See tähendab, et iga ULID sisaldab oma loomise aega täpsusega 1 ms, mis võimaldab ID-sid kronoloogiliselt sortida.
  • Järgmised 16 märki (80 bitti): juhuslik osa, mis tagab unikaalsuse isegi siis, kui mitu ID-d luuakse samal millisekundil. 80 bitti pakub 2^80 = umbes 1,2 × 10^24 võimalikku juhuslikku väärtust, mis teeb kokkupõrke tõenäosuse äärmiselt väikeseks – isegi miljoni ID genereerimisel sekundis on dubleerimise oht tühine.

Kogu string on 26 märki pikk, kasutades ainult Crockfordi base32 tähestiku märke (0–9, A–Z välja arvatud I, L, O, U). See tähendab, et ULID-id on nii URL-ohutud kui ka kergesti loetavad: ei esine segiajamist suur- ja väiketähtede vahel (kõiki saab lugeda nii suurte kui väikestena) ning visuaalselt sarnased märgid (näiteks 1 ja I, O ja 0) on tähestikust eemaldatud.

Crockfordi base32 kodeering: miks just see tähestik?

Crockfordi base32 on spetsiaalselt loodud olema inimloetav ja vältima vigu. Tähestik koosneb numbritest 0–9 ja tähtedest A–Z, millest on välja jäetud:

  • I (võib segi ajada numbriga 1)
  • L (võib segi ajada numbriga 1 või suurtähega I)
  • O (võib segi ajada numbriga 0)
  • U (võib segi ajada tähega V)

Lisaks on kodeering tõstutundetu – see tähendab, et sama ULID stringi saab kirjutada nii suurte kui väikeste tähtedega ja see käitub identselt. See on suur eelis võrreldes UUID-ga, kus suur- ja väiketähtede erinevus on oluline (näiteks segiajamine a ja A vahel võib põhjustada vigu). Praktikas võib ULID-i kopeerida e-kirjast, veebilehelt või käsitsi üles kirjutada ilma mureta, kas tähed on õiges suuruses.

Crockfordi base32 kasutamine on ka põhjus, miks ULID on 26 märki pikk, mitte 36 nagu UUID. Kui UUID kasutab 128 biti esitamiseks kuueteistkümnendsüsteemi (32 märki + 4 sidekriipsu), siis base32 võimaldab iga märgiga kodeerida 5 bitti (2^5 = 32 võimalust), mis annab 26 märki (128 / 5 ≈ 25,6, ümardatuna 26-ni). Täpne jaotus: 48 bitti ajatempli jaoks = 10 märki, 80 bitti juhuslikkuse jaoks = 16 märki.

Võrdlus UUID v4 ja UUID v7-ga

Omadus ULID UUID v4 UUID v7
Pikkus (märke) 26 36 (32 + 4 sidekriipsu) 36 (32 + 4 sidekriipsu)
Ajatempel Jah, 48-bitine millisekundites Ei, täiesti juhuslik Jah, 48-bitine millisekundites (RFC 4122 värskendus)
Tõstutundlikkus Ei (kõik märgid tõstutundetud) Jah (A-F vs a-f) Jah (A-F vs a-f)
Sidekriipsud Ei Jah (4 kohal) Jah (4 kohal)
Sorteeritavus Leksikograafiline loomisaja järgi Sorteerimine juhuslik Leksikograafiline loomisaja järgi
URL-ohutus Täielik (kõik märgid RFC 3986 ohutud) Sidekriipsud ohutud, aga suur-väiketähtede erinevus võib segadust tekitada Sama nagu UUID v4

Peamine erinevus UUID v4-ga on see, et ULID võimaldab ID-de sortimist ilma eraldi ajatempli veeruta. UUID v4 puhul on uued ID-d andmebaasis laiali pillutatud, mis halvendab B-puu indeksi jõudlust. UUID v7 lahendab selle, kuid on endiselt 36 märki pikk ja sisaldab sidekriipse. ULID on lühem, puhtam ja inimloetavam.

Sorteerimiskäitumine ja samal millisekundil loodud ID-d

ULID-id on loodud olema leksikograafiliselt sorteeritavad loomisaja järgi. Kui võrrelda kahte ULID-i stringina, siis varasema ajatempliga ID on alati eespool. See kehtib isegi siis, kui ID-sid on loodud erinevatel masinatel – eeldusel, et nende süsteemikellad on sünkroonitud.

Kui aga mitu ULID-i genereeritakse täpselt samal millisekundil, siis nende järjestus sõltub juhuslikust osast. Teisisõnu, samal millisekundil loodud ID-de puhul ei ole garanteeritud, et need on omavahel kronoloogilises järjekorras. See on ULID-i teadlik disainivalik: esimesed 10 märki on ajapõhised, ülejäänud 16 on juhuslikud. Kui on vaja absoluutset järjestust ka samal millisekundil, tuleks kasutada teistsugust lähenemist (näiteks monotoonne loendur), aga see ohverdaks juhuslikkuse ja suurendaks kokkupõrke tõenäosust. Enamikus rakendustes pole samal millisekundil loodud ID-de täpne järjestus kriitiline – oluline on, et kõik eri ajahetkedel loodud ID-d oleksid korrektses järjestuses.

Kokkupõrke tõenäosus: 80-bitine juhuslik komponent

ULID-i juhuslik osa on 80 bitti. Kui ID-sid genereerida kiirusega 1000 ID-d sekundis (mis on tüüpiline enamikule rakendustele), siis:

  • Ühe millisekundi jooksul võib tekkida mitu ID-d, kuid 80-bitine juhuslik osa tagab, et kokkupõrke tõenäosus on praktiliselt null.
  • Matemaatiliselt: kui N on ID-de arv, siis vähemalt ühe kokkupõrke tõenäosus on ligikaudu N^2 / (2 * 2^80). Isegi kui N = 10^12 (triljon), on tõenäosus umbes 10^-9 ehk üks miljardist. Tegelikes rakendustes genereeritakse harva nii palju ID-sid, seega kokkupõrked on statistiliselt võimatud.

See erineb UUID v4-st, mis kasutab 122-bitist juhuslikku osa (ülejäänud 6 bitti on versiooni ja variandi jaoks). UUID v4 teoreetiline kokkupõrke tõenäosus on veelgi väiksem, kuid praktikas on ka ULID piisavalt turvaline.

Tähtis on märkida, et kõik ID-d genereeritakse brauseris kohapeal, kasutades crypto.getRandomValues() – tugevat krüptograafilist juhuslikkust. Ühtegi ID-d ei saadeta serverisse, mis tagab privaatsuse.

URL-ohutus ja kodeerimine

Kõik Crockfordi base32 märgid (0–9, A–Z, ilma I-L-O-U) on URL-ohutud vastavalt RFC 3986-le. See tähendab, et neid ei pea protsendikodeerima, isegi kui need sisalduvad URL-i tee- või päringuosas. Näiteks UUID puhul tuleb mõnikord sidekriipsudega ettevaatlik olla, aga ULID puhul pole mingeid erisümboleid – ainult numbrid ja tähed. See teeb ULID-id ideaalseks avalike API-de identifikaatoriteks: neid saab panna URL-i ilma igasuguse eeltöötluseta.

Kohalik genereerimine ja privaatsus

Tööriist genereerib kõik ID-d brauseris, kasutades crypto.getRandomValues(). See tähendab, et:

  • Ühtegi andmeid ei saadeta serverisse – isegi mitu korda vajutades jäävad kõik toimingud lokaalseks.
  • Privaatsuse vaatenurgast on see oluline: kui töötad tundlike andmetega (näiteks test-ID-d reaalsüsteemile), ei leki midagi võrku.
  • ID-de loomine on äärmiselt kiire – tuhandete ID-de genereerimine võtab millisekundeid.
  • Status read: "Ready." näitab, et leht on valmis, "Generated." kuvatakse pärast ID-de loomist, ja "Copied all!" ilmub kui kõik ID-d on lõikelauale kopeeritud.

Kasulikud stsenaariumid: kes seda vajab

  • Veebi- ja mobiiliarendajad vajavad lühikesi, URL-ohutuid ID-sid, mida saab sortida loomisaja järgi ilma eraldi ajatempli veeruta. Näiteks sündmuste logimisel või tellimuste haldamisel on ajalise järjestuse säilitamine lihtne.
  • Andmebaasiadministraatorid saavad kasutada ULID-i primaarvõtmena. Kuna uued ID-d on ajaliselt monotoonselt kasvavad, paraneb B-puu indeksi jõudlus – erinevalt UUID v4-st, mis põhjustab indeksi killustumist.
  • API-disainerid soovivad avalikke ID-sid, mida on raske ära arvata (juhuslik osa on piisavalt pikk) ja mis on samas inimloetavad (pole segadust suur- ja väiketähtedega).
  • Kõik, kellele UUID tundub liiga pikk või kohmakas – 26 märki on 10 märgi võrra lühem kui 36, mis võib suurte andmekogumite puhul säästa märkimisväärselt ruumi nii andmebaasis kui ka andmeedastuses.

KKK (Korduma Kippuvad Küsimused)

Miks mul ei ole valikut suurtähtede või sidekriipsude jaoks ULID-i puhul? Sest ULID on olemuslikult tõstutundetu (Crockfordi base32 võimaldab nii suur- kui väiketähti, aga neid koheldakse võrdsetena) ja sidekriipsudeta. Täiendavad lülitid pole vajalikud.

Kas ma saan muuta genereeritavate ID-de arvu rohkem kui 100? Ei, tööriist aktsepteerib ainult väärtusi 1 kuni 100. Kui vajad rohkemaid, saad genereerida mitu korda.

Mis juhtub, kui ma klõpsan üksikut ULID-i? See kopeeritakse lõikelauale. Klõpsates "Copy all" kopeeritakse kogu loend.

Kas ULID-id on garanteeritult unikaalsed nagu UUID v4? Teoreetiliselt on võimalik kokkupõrge, kuid 80-bitine juhuslik komponent muudab selle praktiliselt võimatuks (tõenäosus on äärmiselt väike). Enamiku rakenduste jaoks on ULID piisavalt unikaalne.

Kas ma saan ULID-e kasutada mitmel seadmel ilma dubleerimiseta? Jah, kui iga seade kasutab oma süsteemikella ajatemplit ja juhuslikkust, on ID-d unikaalsed. Kuid samal millisekundil loodud ID-d võivad olla identsed ainult siis, kui juhuslik osa langeb kokku – see on aga ülimalt ebatõenäoline.

Miks on ajatempel just millisekundites? Millisekundid on piisavalt täpsed enamiku rakenduste jaoks ning 48 bitti mahutab ajavahemiku kuni aastani 10889 (2^48 ms ≈ 8924 aastat alates 1970). See on palju kaugemale kui enamik süsteeme kunagi vajavad.