Kas yra ULID ir kuo šis įrankis skiriasi?
Šiame puslapyje galite generuoti ULID – 26 simbolių ilgio, nejautrius didžiosioms / mažosioms raidėms identifikatorius, kuriuos galima rūšiuoti pagal sukūrimo laiką. Nuo kitų to paties įrankio formatų (pvz., UUID v4, UUID v7 ar NanoID) jis skiriasi tuo, kad nenaudoja brūkšnelių, yra trumpesnis už UUID (26 simboliai prieš 36), o jo abėcėlė yra Crockfordo base32 – tik raidės ir skaitmenys be vizualiai dviprasmiškų simbolių (I, L, O, U praleidžiami). Dėl to ULID yra URL saugus – nereikia jokio procentinio kodavimo.
Skirtingai nei kiti to paties įrankio formatai, ULID čia neturi perjungimo mygtukų didžiosioms raidėms ar brūkšneliams įjungti – tai yra pastovi savybė. Jūs pasirenkate formatą, nurodote, kiek identifikatorių norite (nuo 1 iki 100), ir įrankis akimirksniu pateikia sąrašą. Kiekvieną ULID galima nukopijuoti atskirai spustelėjus ant jo arba visus iš karto naudojant mygtuką „Copied all!“. Būsenos pranešimai – „Ready.“, „Generated.“ ir „Copied all!“ – informuoja, kas vyksta.
Visa generacija vyksta vietiniame naršyklėje naudojant crypto.getRandomValues() – jokie duomenys nesiunčiami į serverį. Tai užtikrina privatumą ir leidžia dirbti net neprisijungus.
ULID vidinė struktūra: laiko žyma ir atsitiktinė dalis
Kiekvienas ULID iš viso yra 128 bitai, padalyti į dvi dalis:
- Pirmi 10 simbolių (48 bitai) – laiko žyma milisekundžių tikslumu. Ji užkoduota Crockford base32, todėl pirmieji simboliai keičiasi laikui bėgant. Dėl to ULID eilutės, sukurtos vėliau, yra leksikografiškai didesnės už ankstesnes.
- Likę 16 simbolių (80 bitų) – atsitiktinė dalis, sukurta naršyklės kriptografiniu atsitiktinių skaičių generatoriumi.
Pavyzdžiui, ULID 01ARZ3NDEKTSV4RRFFQ69G5FAV iššifruojamas taip: 01ARZ3NDEK yra laiko žyma (atitinka tam tikrą Unix milisekundę), o TSV4RRFFQ69G5FAV – atsitiktinis komponentas.
Kadangi laiko žyma yra pirmoje vietoje, ULID galima rūšiuoti pagal sukūrimo laiką tiesiog surūšiavus juos kaip eilutes. Tačiau ribotas milisekundžių tikslumas reiškia, kad per tą pačią milisekundę sugeneruoti ULID nebus griežtai išrikiuoti – jų tvarką nulems atsitiktinė dalis.
Crockford base32 abėcėlė ir kodavimas
Crockford base32 naudoja 32 simbolius: skaitmenis 0–9 ir raides A–Z, išskyrus I, L, O, U (jų praleidžiama, kad būtų išvengta painiavos su 1, l, 0 ir V). Tai reiškia, kad ULID yra nejautrūs didžiosioms / mažosioms raidėms – 01ARZ3NDEKTSV4RRFFQ69G5FAV ir 01arz3ndektsv4rrffq69g5fav reiškia tą patį identifikatorių.
Kodavimo procesas ima 128 bitų dvejetainę reikšmę, padalija ją į 5 bitų grupes (iš viso 26 grupės, nes 26 × 5 = 130, bet paskutiniai 2 bitai nenaudojami – ULID naudoja tik 128 iš 130 bitų, todėl paskutiniai du simboliai turi mažesnį efektyvų bitų skaičių) ir kiekvieną grupę atvaizduoja į Crockford abėcėlės simbolį. Rezultatas – 26 simbolių be brūkšnelių eilutė.
Šis kodavimas užtikrina, kad identifikatoriuose nėra simbolių, kuriuos būtų lengva supainioti (pvz., „I“ ir „1“ arba „O“ ir „0“). Tai ypač svarbu, kai ULID turi būti perrašomi rankomis arba diktuojami balsu.
ULID ir UUID palyginimas: ką prarandate ir laimite?
| Savybė | ULID | UUID v4 | UUID v7 |
|---|---|---|---|
| Ilgis simboliais | 26 | 36 (su brūkšneliais) | 36 (su brūkšneliais) |
| Bendra bitų erdvė | 128 bitai | 122 bitai (atsitiktiniai) | 128 bitai (laiko žyma + atsitiktiniai) |
| Rūšiavimas pagal laiką | Taip, milisekundžių tikslumu | Ne | Taip, milisekundžių tikslumu |
| Brūkšneliai | Nėra | Yra (4 brūkšneliai) | Yra (4 brūkšneliai) |
| Didžiosios / mažosios raidės | Nereikšmingos | Skiriamos (standarte nurodyta mažosiomis) | Skiriamos |
| URL saugumas | Nereikia kodavimo | Brūkšnelius reikia užkoduoti | Brūkšnelius reikia užkoduoti |
ULID laimi trumpumu ir URL saugumu, taip pat galimybe rūšiuoti pagal laiką (tai naudinga duomenų bazių indeksams – nauji įrašai dedami į pabaigą, o ne atsitiktines vietas). UUID v4 pranašumas – didesnis atsitiktinumas (122 bitai vietoj 80 bitų atsitiktinės dalies), tačiau ULID naudoja 48 bitus laiko žymai, todėl realiai išsaugo 128 bitų erdvę, bet tik 80 bitų yra atsitiktiniai.
UUID v7 yra panašus – jis taip pat sujungia laiko žymą su atsitiktiniais bitais, tačiau jo atvaizdavimas išlieka 36 simboliai su brūkšneliais. ULID yra kompaktiškesnis.
Rūšiavimas pagal laiką ir indeksavimas duomenų bazėse
Viena pagrindinių ULID priežasčių naudoti yra jų tinkamumas kaip pirminiai raktai duomenų bazėse, ypač tose, kurios naudoja B-medžius (pvz., PostgreSQL, MySQL, SQL Server). Įprasti atsitiktiniai UUID v4 išbarsto naujus įrašus po visą indeksą, todėl dažnai tenka perskirstyti puslapius, o tai mažina našumą. ULID, priešingai, didėja monotoniškai (bent jau milisekundžių ribose), todėl nauji raktai patenka į paskutinę indekso dalį, o tai žymiai pagreitina įrašymą.
Tačiau reikia atsiminti: per tą pačią milisekundę sugeneruoti ULID gali būti bet kokia tvarka (priklauso nuo atsitiktinės dalies). Jei jūsų sistema generuoja ULID labai dideliu dažniu (pvz., tūkstančius per milisekundę), teks susitaikyti su šiuo neapibrėžtumu arba pridėti papildomą tvarkymo lauką (pvz., didėjantį sekos numerį). Daugeliui programų toks laipsnis nėra kritinis.
Taip pat verta paminėti, kad ULID rūšiavimas pagal laiką galioja tik tada, kai lyginate eilutes kaip eilutes (pagal abėcėlę). Kadangi pirmieji 10 simbolių yra laiko žyma, o toliau – atsitiktinė dalis, dvi skirtingos milisekundės visada bus išrikiuotos teisingai.
Susidūrimo tikimybė ir saugumas
Atsitiktinė ULID dalis yra 80 bitų. Teoriškai, jei generuojate 1 milijoną ULID per sekundę, tikimybė susidurti su dubliku per vieną milisekundę yra itin maža (maždaug viena iš kelių milijardų). Praktiškai, jei ULID generuojami ne viename ir tame pačiame milisekundės intervale (t.y. skirtingomis milisekundėmis), jų laiko žymos garantuoja unikalumą – atsitiktinė dalis tik užpildo likusią erdvę. Tačiau jei du ULID sugeneruojami toje pačioje milisekundėje, jie gali sutapti, jei atsitiktinės dalys bus identiškos. Tikimybė, kad 80 bitų atsitiktinė dalis pasikartotų per vieną milisekundę, yra maždaug 1 / (2^80), o tai praktiškai nereikšminga.
ULID nėra skirti saugoti paslėptų duomenų arba užkirsti kelią atspėjimui – atsitiktinė dalis yra tik 80 bitų, todėl ją atspėti yra lengviau nei visą UUID v4 (122 bitai). Jei jums reikalingi neatskleidžiami, neprognozuojami identifikatoriai, ULID nėra geriausias pasirinkimas. Jie labiau tinka viešiems, tačiau nerūšiuojamiems identifikatoriams (pvz., el. pašto patvirtinimo nuorodoms – nerekomenduojama) arba vidiniams duomenų bazės raktams.
Dažnai užduodami klausimai
Kuo ULID skiriasi nuo UUID v4?
ULID yra trumpesnis (26 vs 36 simboliai), neturi brūkšnelių, yra nejautrus raidžių dydžiui ir leidžia rūšiuoti pagal sukūrimo laiką. UUID v4 naudoja 122 atsitiktinius bitus, o ULID – 80 atsitiktinių bitų + 48 bitų laiko žymą.
Ar galiu gauti daugiau nei 100 ULID vienu metu?
Ne, šiame puslapyje galima pasirinkti nuo 1 iki 100. Jei reikia daugiau, teks generuoti kelis kartus.
Ar ULID yra URL saugūs be papildomo kodavimo?
Taip. Crockford base32 naudoja tik raides ir skaitmenis, todėl nėra jokių simbolių, kuriems reikėtų procentinio kodavimo pagal RFC 3986.
Kodėl puslapyje nėra galimybės įjungti didžiųjų raidžių ar brūkšnelių?
Nes ULID standartas yra nejautrus didžiosioms / mažosioms raidėms ir nenumato brūkšnelių. Pridėti tokius perjungimus būtų klaidinantis.
Ar šie ULID generuojami serveryje?
Ne. Visi identifikatoriai sukuriami jūsų naršyklėje naudojant crypto.getRandomValues(). Jokie duomenys nepalieka jūsų kompiuterio.
Kokia tikimybė gauti dubliuojantį ULID?
Labai maža – jei generuojate keliasdešimt ULID per vieną milisekundę, 80 bitų atsitiktinė dalis praktiškai garantuoja unikalumą. Net jei generuotumėte 100 ULID per vieną milisekundę, tikimybė, kad du sutaptų, yra maždaug 1 / (2^80) ~ 10^-24.