Codificare / decodificare Base62

Convertește un număr sau un șir de octeți cu Base62: 62 de caractere formate din cifre, litere mari și litere mici, niciunul care să nu necesite escapare într-un query URL sau în text HTML. De aceea link-urile scurte și ID-urile cu autoincrement se scriu astfel. Două moduri: un număr zecimal (un ID devine un cod scurt) și octeți (text sau intrare hexazecimală). De asemenea: Base64 | Base32 / Base58 | Base91.
Toată prelucrarea are loc local în browser — datele nu sunt încărcate niciodată pe vreun server.

Base62 nu este cunoscut? Ce este Base62 — explicat pe înțelesul tuturor (cu exemple lucrate, cele trei alfabete și capcanele).
Alfabet:
Completează rezultatul la o lățime fixă: 0 = fără umplutură. Umplutura repetă caracterul zero al alfabetului selectat, deci același număr se completează diferit în alfabetul cu literele întâi.
Cum funcționează:
Intrarea este:
Cum funcționează:
Ieșirea ca:
Ctrl+Enter în intrare rulează modul activ.
Se alege Codificare sau Decodificare și se apasă butonul de acțiune. Butonul Autotest rulează fiecare exemplu documentat, fiecare lungime de la 0 la 64 de octeți și o serie de numere zecimale în toate cele trei alfabete, și raportează aici numărul.
Cele trei alfabete, tipărite integral: Base62 nu are un organism de standardizare în spate, deci alfabetul nu este garantat între implementări. Acestea sunt cele trei ordini care apar efectiv în practică; fiecare este tipărită caracter cu caracter, cu valoarea sa, astfel încât orice rezultat poate fi urmărit până la alfabetul exact care l-a produs. Celula umbrită este caracterul care înseamnă zero, care nu este același caracter în toate cele trei.
Base62 este sensibil la majuscule în fiecare dintre cele trei ordini: o literă mare și forma ei mică denumesc aproape întotdeauna valori diferite, deci un cod care a trecut printr-un pas de transformare în litere mici este un alt număr, nu o eroare.
Base62 este sensibil la majuscule în fiecare dintre cele trei ordini: o literă mare și forma ei mică denumesc aproape întotdeauna valori diferite, deci un cod care a trecut printr-un pas de transformare în litere mici este un alt număr, nu o eroare.
Lungimea aceluiași șir de octeți în fiecare codificare:
Cât de mare poate fi o intrare acceptată de pagină și de ce: fiecare mod de aici convertește printr-un singur număr mare, iar conversia unui număr mare costă timp proporțional cu pătratul lungimii. Aceasta este o proprietate a formatului în sine, nu a acestei pagini: orice instrument care implementează Base62 real are aceeași formă de limită. Cifrele de mai jos provin dintr-un instrument de măsurare a timpului care rulează rutinele paginii, nu dintr-o filă care rulează, deci sunt intenționat pesimiste: un browser de desktop termină de obicei de câteva ori mai repede, iar această marjă acoperă un telefon lent. Limitele sunt stabilite astfel încât chiar și cazul lent să se termine, în loc să înghețe fila.
Peste limita moale, primul clic explică costul și cere un al doilea clic înainte să ruleze; peste limita tare, pagina refuză, în loc să înghețe fila timp de câteva secunde fără nicio modalitate de a afișa progresul. Modul octeți se numără în octeți la codificare și în caractere la decodare, iar numărul de caractere este întotdeauna cel mai mare: 2 048 de octeți se tipăresc în aproximativ 2 751 de caractere, ceea ce depășește limita de caractere, deci o sarcină utilă de aproximativ 1 520 de octeți sau mai puțin este ceea ce supraviețuiește unui dus-întors pe această pagină. Pentru date binare simple de orice dimensiune reală, Base64 și Base91 sunt liniare și nu au o asemenea limită.
Ce este Base62?

Base62 este un mod de a scrie un număr cu nimic altceva decât caractere care supraviețuiesc lipirii oriunde: cele zece cifre, cele 26 de litere mari și cele 26 de litere mici. Fără semne de punctuație, fără spații, fără caracter de umplutură, nimic care trebuie escapat înainte de a intra într-un URL, un nume de fișier, un cookie sau o cheie de bază de date. Zece plus 26 plus 26 fac 62, și de aici vine numele.

Versiunea de 30 de secunde: numărul 12345 se scrie 3D7, iar 1234567890 se scrie 1LY7VK. Întoarcerea este aceeași operație în sens invers și are nevoie de alfabetul exact care a produs codul — un alt alfabet transformă aceleași șase caractere într-un alt număr, fără nicio eroare afișată.

Această pagină face două lucruri înrudite, iar diferența dintre ele contează mai mult decât orice altceva de pe pagină:

  • Modul întreg tratează intrarea ca pe un număr. Un ID zecimal precum 1234567890 devine 1LY7VK, iar zerourile de la începutul intrării nu fac parte din valoare, deci nu se mai întorc.
  • Modul octeți tratează intrarea ca pe un șir de octeți. Octeții se citesc ca un singur număr uriaș, big-endian, și apoi se împart la 62, adică aceeași aritmetică aplicată altei mărimi. Aici numărul de octeți zero de la început se păstrează, câte un caracter zero pentru fiecare octet zero.
De unde vin cei 62 și ce costă

62 nu este o putere a lui doi, iar acest singur fapt modelează tot restul. Codificările familiare sunt construite prin tăierea intrării în grupuri fixe de biți: 4 biți devin un caracter hexazecimal, 6 biți un caracter Base64, 5 biți un caracter Base32. Base62 nu poate face asta, pentru că niciun număr întreg de biți nu încape într-un caracter cu 62 de valori — 5 biți numesc doar 32 de valori, iar 6 biți numesc 64. Așa că Base62 trece prin aritmetică: se citește întreaga intrare ca un singur întreg și se tipărește în baza 62.

Un caracter transportă atunci log2(62) = 5,954 biți, foarte aproape de cei 6 ai Base64, iar în modul zecimal un caracter înlocuiește log62(10) = 1,792 cifre zecimale. Câteva consecințe care merită cunoscute înainte de a alege o lungime:

Lungimea coduluiValorile pe care le poate numiÎn practică
4 caractere624 = 14 776 336Suficient pentru un contor care rămâne sub opt cifre și încape în spațiul unui număr de telefon.
6 caractere626 = 56 800 235 584Forma obișnuită a unui cod de ID. Un ID zecimal de zece cifre încape în șase caractere.
7 caractere627 = 3 521 614 606 208Peste intervalul unui contor pe 32 de biți cu două ordine de mărime, în lățimea unui slug scurt de link.
11 caractere6211 = 52 036 560 683 837 093 888Mai mult decât 264 = 18 446 744 073 709 551 616, deci un număr complet pe 64 de biți încape în unsprezece caractere.

Invers, 1 000 de cifre zecimale au nevoie de aproximativ 558 de caractere, iar 4 096 de cifre zecimale au nevoie de 2 285. Economia este reală, dar limitată: Base62 scurtează un număr zecimal cu aproximativ 44%, și nu întrece niciodată cele mai dense codificări tipăribile, pentru că 5,954 biți pe caracter sunt pur și simplu mai puțin decât 6,4 sau 6,5.

Modul întreg: ce se întâmplă cu zerourile de la început

Un întreg are o singură formă scrisă canonică, iar aceasta începe cu caracterul zero al alfabetului, care este 0 în cele două ordini cu cifrele întâi și A în ordinea cu literele întâi. Tot ce se află înaintea primului caracter semnificativ este umplutură, iar umplutura nu face parte din valoare: 00012345 și 12345 devin amândouă 3D7. Dacă se dorește o lățime fixă — de exemplu un cod de șapte caractere care trebuie aliniat într-o coloană — caseta Completează rezultatul la o lățime fixă de pe pagină repetă caractere zero până se atinge lățimea, astfel încât 12345 la lățimea 7 se tipărește 00003D7 în alfabetul cu cifrele întâi și AAAADNH în cel cu literele întâi. Umplutura este cosmetică: caracterele de la început nu adaugă nimic valorii, iar decodarea oricăruia dintre șiruri dă înapoi 12345, pentru că 0 × 626 și 0 × 625 sunt amândouă zero, indiferent ce caracter scrie zeroul.

Decodarea unui șir completat funcționează, deci, și ea, iar pagina raportează câte dintre caracterele de la început au fost zerouri, astfel încât diferența dintre „codul are șapte caractere” și „valoarea a avut nevoie de trei caractere” să nu fie niciodată un mister.

Modul octeți: aceeași aritmetică pe un șir de octeți

Modul octeți citește octeții de intrare ca un singur întreg big-endian — întregul șir de octeți este tratat ca un singur număr, oricât de lung ar fi — și tipărește acel număr în baza 62. Deoarece un octet conține 8 biți, iar un caracter ține 5,954 dintre ei, modul octeți nu este compresie: are nevoie de aproximativ 134% din dimensiunea intrării, puțin mai rău decât cei 133% ai Base64. Pe exemplul de 92 de octeți din tabelul de dimensiuni de mai sus, 92 de octeți se tipăresc în 124 de caractere Base62, iar Base64 tipărește tot 124 (123 dintre ele înainte de umplutura =). Base62 pierde în fața Base64 la densitate și câștigă la siguranța caracterelor, iar acesta este compromisul pe care îl face fiecare link scurt și fiecare cod de invitație, în mod deliberat.

Octeții zero de la început se păstrează, iar acest lucru este ușor de greșit în ambele sensuri. Doi octeți zero de la început, plus 0x01, se tipăresc ca 001 în alfabetul cu cifrele întâi și ca AAB în cel cu literele întâi, pentru că caracterele de la început scriu zero, câte unul pentru fiecare octet zero. Un șir de octeți format dintr-un singur 0x00 se tipărește ca un singur caracter 0, iar un șir format dintr-un singur 0x01 se tipărește ca 1. Acesta este singurul loc unde modul octeți și modul întreg arată diferit, deși rulează același algoritm.

Costul întregii situații este că modul octeți moștenește timpul pătratic al aritmeticii: pentru 1 024 de octeți se estimează aproximativ o treime de secundă, iar pentru 2 048 de octeți aproximativ 1,3 secunde, aceleași cifre ca în tabelul de limite de mai sus. De aceea modul octeți de aici este limitat la 2 048 de octeți la intrare și la 2 048 de caractere la ieșire — 2 048 de octeți se tipăresc în aproximativ 2 751 de caractere, deci aproximativ 1 520 de octeți este cea mai mare sarcină utilă care supraviețuiește unui dus-întors prin această pagină — și de aceea modul octeți de pe această pagină este o referință pentru valori mici, nu un înlocuitor pentru Base64 sau Base91 pentru fișiere reale.

Cele trei alfabete și de ce alfabetul este întreaga poveste

Caracterele unui alfabet sunt o secvență fixă, iar valoarea unui caracter este poziția sa în această secvență. Mutarea secvenței schimbă ce înseamnă fiecare caracter. Sunt trei ordini în uz larg, iar acesta este același număr scris în fiecare dintre ele:

Zecimal0-9 apoi A-Z apoi a-z0-9 apoi a-z apoi A-ZA-Z apoi a-z apoi 0-9
000A
61zZ9
621010BA
12 3453D73d7DNH
1 234 567 8901LY7VK1ly7vkBViHfU

Citite cele trei ultime coloane ca un singur alfabet, formează o schemă coerentă. Citite ca interschimbabile, se destramă, pentru că decodarea este oarbă la alfabet în cel mai rău mod: orice caracter al intrării se află în toate cele trei alfabete, deci un alfabet greșit nu produce nicio eroare, ci doar un alt număr.

Un codCitit ca 0-9 A-Z a-zCitit ca 0-9 a-z A-ZCitit ca A-Z a-z 0-9
3D712 34513 957211 665
1LY7VK1 234 567 8901 624 950 79248 723 527 772

Majusculele sunt o a doua versiune, mai ascuțită, a aceleiași capcane. Base62 este sensibil la majuscule în orice ordine, deci transformarea unui cod în litere mici îl rescrie în tăcere: 1LY7VK înseamnă 1 234 567 890 în alfabetul cu cifrele întâi, pe când 1ly7vk înseamnă 1 624 950 792 în același alfabet — și înseamnă 1 234 567 890 în alfabetul cu cifrele urmate de litere mici, pentru că această ordine este exact cea cu cifrele întâi, cu cele două tipuri de litere inversate. Nici caracterul zero nu este comun: cele două ordini cu cifrele întâi scriu zero ca 0, iar ordinea cu literele întâi îl scrie ca A, deci acest alfabet nu începe deloc cu o cifră.

Base62 alături de celelalte codificări
CodificareBiți pe caracterDimensiune față de intrareNote
Base16 (hex)4200%Două caractere pe octet, citire trivială, fără alfabet de căutat.
Base325160%Insensibil la majuscule și sigur pentru dictare, cel mai risipitor din grup.
Base36 (0-9 a-z)~5,17~155%Doar cifre și litere mici, deci supraviețuiește unui pipeline care transformă în litere mici. 12345 este 9ix.
Base58~5,86~137%Ales pentru adrese, nu pentru densitate: patru caractere care se confundă sunt eliminate, în loc să fie ordonate. Vezi Base32 / Base58.
Base62~5,95~134%Fiecare caracter este o cifră sau o literă, deci nimic nu se escapează niciodată. Densitatea se află între Base58 și Base64.
Base646133%Implicit peste tot, cu prețul +, / și =, cele trei caractere care forțează escaparea. Vezi Convertor Base64.
Ascii85 / Base856,4125%5 caractere la 4 octeți, dar împarte la 85 și alfabetul său trebuie pus între ghilimele. Vezi Ascii85.
Base91~6,5~123%Cel mai dens dintre acestea și cel al cărui rezultat este cel mai puțin sigur de lipit fără escapare. Vezi Base91.

Procentele sunt costuri asimptotice, rotunjite; numărul măsurat de caractere pentru o intrare reală de 92 de octeți se află în tabelul de dimensiuni de mai sus pe această pagină. În modul întreg, comparația merge în sens invers, pentru că intrarea este text zecimal, nu octeți: acolo Base62 este cu aproximativ 44% mai scurt decât cifrele pe care le înlocuiește, iar Base36 cu aproximativ 36% mai scurt, de aceea un cod de ID este de obicei Base62 sau Base36 și nu Base58.

Ce nu este Base62
  • Nu este un standard. Nu există RFC și nicio specificație. Niciun organism de standardizare nu a definit vreodată Base62, de aceea alfabetul nu este garantat și de aceea această pagină tipărește toate cele trei ordini, în loc să aleagă una în tăcere.
  • Nu este criptare. Este o schimbare de bază, nimic mai mult. Oricine cunoaște alfabetul o inversează într-o singură trecere, iar nu există nicio cheie, niciun salt și nicio formă de secretitate.
  • Nu este compresie. Modul octeți mărește datele cu aproximativ o treime. Modul întreg doar pare compresie, pentru că textul zecimal este, din start, un mod ineficient de a scrie un număr.
  • Nu este insensibil la majuscule. Base32 poate fi scris cu litere mici și citit înapoi; Base62 nu. Un cod care trece printr-un sistem care normalizează majusculele este un cod corupt.
  • Nu se autoverifică. Nu există sumă de control și nici caracter de control, așa că un singur caracter greșit dă un rezultat valid la aspect, dar cu altă valoare. Dacă asta contează, ordinea Bitcoin vine cu o sumă de control — vezi secțiunea Base58Check din Base32 / Base58.
  • Nu are lungime fixă. Numărul de caractere crește odată cu valoarea, așa că un contor care pornește de la 1 și ajunge la 627 trece de la un caracter la opt. Se completează la o lățime fixă atunci când este nevoie de o coloană stabilă.
Capcane care chiar mușcă
  • Alfabetul este răspunsul la nouă din zece mistere. Dacă un alt instrument dă un cod diferit pentru același număr, se compară cele două alfabete caracter cu caracter, înainte de a bănui o eroare. Tabelul de mai sus arată aceeași valoare în trei alfabete, iar toate trei sunt corecte.
  • Un alfabet greșit eșuează în tăcere. Nu există o cale de eroare pentru asta: 3D7 se decodează în 12 345, 13 957 sau 211 665, în funcție doar de ordinea presupusă. Se verifică primul caracter, cel mai probabil să fie o umplutură cu zero, și dacă alfabetul are cifre sau litere la început.
  • Zerourile de la început înseamnă două lucruri diferite. În modul întreg, 00012345 și 12345 sunt același număr și se tipăresc identic. În modul octeți, un octet zero de la început este date, și se tipărește ca un caracter zero în plus. Eliminarea unuia dintre acele caractere schimbă șirul de octeți.
  • Normalizarea majusculelor distruge un cod. O adresă de e-mail, un nume de gazdă sau o cale Windows pot fi transformate în litere mici în tranzit. Un cod Base62 nu poate supraviețui asta, și de aceea încă există Base36.
  • Intrările lungi sunt lente, nu doar mari. Conversia este aritmetică pe întreaga intrare deodată, deci dublarea lungimii intrării înmulțește timpul cu patru. Pagina refuză intrările peste limitele sale măsurate, în loc să se blocheze; tabelul dimensiunilor de mai sus dă cifrele măsurate.
  • Un șir Base62 nu dovedește nimic. Deoarece aproape orice șir de cifre și litere se decodează fără obiecții, un slug arbitrar de URL se va decoda într-un anumit număr. Un cod are sens doar dacă sistemul care l-a emis stochează și maparea.
Răspunsuri rapide

„De ce dă un alt instrument Base62 un alt cod pentru același număr?”

Pentru că alfabetul diferă. Base62 nu are o specificație cu care să intre în contradicție, deci implementările aleg o ordine: cifrele și literele mari primele, cifrele și literele mici primele sau literele înaintea cifrelor. Selectorul de alfabet din partea de sus a paginii se schimbă, pentru a vedea alăturat toate cele trei răspunsuri.

„Este Base62 sigur într-un URL?”

Da, în toate cele trei ordini. Toate cele 62 de caractere sunt litere și cifre neescapate, deci niciunul nu este extins într-un triplet procentual într-un șir de interogare și niciunul nu încheie un URL, un segment de cale sau un atribut HTML. Acesta este motivul întreg pentru care link-urile scurte sunt în Base62, și nu în Base64.

„Care este mai mic, Base62 sau Base64?”

Pentru octeți, Base64 este foarte puțin mai mic: aproximativ 133% din intrare, față de aproximativ 134%. Pe exemplul de 92 de octeți de mai sus, cele două ajung la egalitate, cu 124 de caractere. Pentru numere zecimale, Base62 scurtează textul cu aproximativ 44%, și acolo este câștigul practic.

„Pot decoda un șir Base64 cu această pagină?”

Nu, și nu va semnala că a eșuat. Cele două alfabete se suprapun în toate cele 62 de caractere, așa că un șir Base64 este de obicei și el „valid” ca intrare aici și pur și simplu se decodează într-un alt număr. Pentru Base64 se folosește Base64.

„Are un cod Base62 o lungime maximă?”

Nu, în teorie algoritmul nu are o limită. În practică, pagina se oprește la 4 096 de cifre zecimale, sau 2 048 de octeți, pentru că aritmetica din spatele ei este pătratică, iar fila ar îngheța fără să existe nimic pe ecran care să explice de ce. Tabelul de limite de mai sus de pe această pagină listează cifrele măsurate.

„De unde știu că rezultatul de pe această pagină este corect?”

Se apasă Autotest. Rulează fiecare exemplu documentat, fiecare lungime de octeți de la 0 la 64 și o serie de numere zecimale în toate cele trei alfabete, compară valorile returnate cu ce a intrat și verifică din nou că toate cele 62 de caractere ale fiecărui alfabet sunt sigure într-un URL. Butonul Exemplu compară, în plus, cele trei rezultate ale sale cu valorile înregistrate în fișierul de date al paginii, care au fost verificate față de o a doua implementare independentă cu numere mari, păstrată în uneltele de testare ale acestui site.

Standarde și creditare

Nu există un standard de implementat aici: Base62 este o convenție, nu o specificație, iar cele trei alfabete tipărite mai sus sunt cele care apar în software-ul real. Această pagină îl implementează cu rutinele proprii ale site-ului pentru numere mari, scrise în aritmetică simplă pe tablouri de cifre, astfel încât nicio dimensiune să nu fie limitată vreodată de tipul numeric JavaScript.

Textul paginii a fost scris pentru acest site. Fiecare exemplu lucrat de pe această pagină a fost produs de codul paginii și apoi verificat față de o a doua implementare independentă, care folosește numere mari native și este păstrată în uneltele de testare ale acestui site; aceeași implementare a verificat și tabelele de exemple și de dimensiuni din fișierul de date.