Che cos'è la Base62?
La Base62 è un modo di scrivere un numero usando solo i caratteri che sopravvivono a essere incollati ovunque: le dieci cifre, le 26 lettere maiuscole e le 26 minuscole. Nessuna punteggiatura, nessuno spazio, nessun carattere di riempimento, nulla che debba essere sottoposto a escape prima di finire in un URL, in un nome di file, in un cookie o in una chiave di database. Dieci più 26 più 26 fa 62, ed è da lì che viene il nome.
La versione in 30 secondi: il numero 12345 si scrive 3D7, e 1234567890 si scrive 1LY7VK. Il percorso inverso è la stessa operazione al contrario, e richiede l'esatto alfabeto che ha prodotto il codice — un alfabeto diverso trasforma gli stessi sei caratteri in un altro numero, senza alcun messaggio d'errore.
Questa pagina svolge due compiti collegati, e la differenza tra i due conta più di ogni altra cosa in questa pagina:
- Modalità intero tratta l'input come un numero. Un ID decimale come
1234567890 diventa 1LY7VK, e gli zeri iniziali dell'input non fanno parte del valore, quindi non ritornano. - Modalità byte tratta l'input come una stringa di byte. I byte vengono letti come un unico grande intero big-endian e poi divisi per 62, che è la stessa aritmetica applicata a una quantità diversa. Qui il numero di byte zero iniziali sopravvive, un byte zero per ogni carattere zero.
Da dove viene il 62, e che cosa costa
62 non è una potenza di due, e questo singolo fatto determina tutto il resto. Le codifiche familiari si costruiscono tagliando l'input in gruppi di bit di lunghezza fissa: 4 bit stampano un carattere esadecimale, 6 bit un carattere Base64, 5 bit un carattere Base32. La Base62 non può farlo, perché nessun numero intero di bit corrisponde a un carattere di 62 valori — 5 bit identificano solo 32 valori, 6 bit ne identificano 64. Quindi la Base62 passa attraverso l'aritmetica: legge l'intero input come un unico intero e lo stampa in base 62.
Un carattere porta allora log2(62) = 5,954 bit, molto vicino ai 6 della Base64, e in modalità decimale un carattere sostituisce log62(10) = 1,792 cifre decimali. Alcune conseguenze utili da sapere prima di scegliere una lunghezza:
| Lunghezza del codice | Valori che può identificare | In pratica |
| 4 caratteri | 624 = 14.776.336 | Abbastanza per un contatore che resta sotto gli otto cifre, e ci sta nello spazio di un numero di telefono. |
| 6 caratteri | 626 = 56.800.235.584 | La forma usuale di un codice ID. Un ID decimale di dieci cifre sta in sei caratteri. |
| 7 caratteri | 627 = 3.521.614.606.208 | Oltre l'intervallo di un contatore a 32 bit di due ordini di grandezza, nella larghezza di uno slug di link breve. |
| 11 caratteri | 6211 = 52.036.560.683.837.093.888 | Più di 264 = 18.446.744.073.709.551.616, quindi un numero completo a 64 bit sta in undici caratteri. |
Nel verso opposto, 1.000 cifre decimali richiedono circa 558 caratteri, e 4.096 cifre decimali ne richiedono 2.285. Il risparmio è reale ma limitato: la Base62 accorcia un numero decimale di circa il 44%, e non batte mai le codifiche stampabili più dense, perché 5,954 bit per carattere sono semplicemente meno di 6,4 o 6,5.
Modalità intero: che cosa succede agli zeri iniziali
Un intero ha un'unica forma scritta canonica, che inizia con il carattere zero dell'alfabeto, cioè 0 nei due ordinamenti con prima le cifre e A nell'ordinamento con prima le lettere. Tutto ciò che sta a sinistra del primo carattere significativo è riempimento, e il riempimento non fa parte di un valore: 00012345 e 12345 diventano entrambi 3D7. Se si vuole una larghezza fissa — per esempio un codice di sette caratteri che deve allinearsi in una colonna — la casella Riempia il risultato a una larghezza fissa della pagina ripete i caratteri zero finché non si raggiunge la larghezza, quindi 12345 alla larghezza 7 stampa 00003D7 nell'alfabeto con prima le cifre e AAAADNH in quello con prima le lettere. Il riempimento è cosmetico: quei caratteri iniziali non aggiungono nulla al valore, e decodificare l'una o l'altra stringa restituisce 12345, perché 0 × 626 e 0 × 625 sono entrambi zero, qualunque carattere scriva lo zero.
Anche decodificare una stringa riempita quindi funziona, e la pagina riporta quanti dei caratteri iniziali erano caratteri zero, così la differenza tra "il codice è lungo sette caratteri" e "il valore richiedeva tre caratteri" non è mai un mistero.
Modalità byte: la stessa aritmetica su una stringa di byte
La modalità byte legge i byte di input come un unico intero big-endian — l'intera stringa di byte è trattata come un singolo numero, di qualunque lunghezza sia — e stampa quel numero in base 62. Poiché un byte contiene 8 bit e un carattere ne rappresenta 5,954, la modalità byte non è compressione: richiede circa il 134% della dimensione dell'input, leggermente peggio della Base64 che è al 133%. Sul campione di 92 byte usato nella tabella delle dimensioni sopra, 92 byte diventano 124 caratteri Base62, e anche la Base64 ne stampa 124 (123 prima del riempimento =). La Base62 perde contro la Base64 in densità e vince nella sicurezza dei caratteri, che è il compromesso che ogni link breve e ogni codice d'invito fa di proposito.
Gli zeri byte iniziali sono conservati, e questo è facile da sbagliare in entrambe le direzioni. Due byte zero iniziali seguiti da 0x01 stampano 001 nell'alfabeto con prima le cifre e AAB in quello con prima le lettere, perché i caratteri iniziali indicano zero e sono uno per ogni byte zero. Una stringa di byte composta da un solo 0x00 stampa il singolo carattere 0, e una stringa di un solo 0x01 stampa 1. È l'unico punto in cui la modalità byte e la modalità intero sembrano diverse pur eseguendo lo stesso algoritmo.
Il costo di tutto questo è che la modalità byte eredita la complessità quadratica dei tempi dell'aritmetica: 1.024 byte sono stimati in circa un terzo di secondo e 2.048 byte in circa 1,3 secondi, gli stessi valori indicati nella tabella dei limiti sopra. Per questo la modalità byte qui è limitata a 2.048 byte in uscita e a 2.048 caratteri in ritorno — 2.048 byte diventano circa 2.751 caratteri, quindi circa 1.520 byte è il carico utile più grande che sopravvive a un andata e ritorno su questa pagina — e per questo la modalità byte di questa pagina è un riferimento per valori piccoli, non un sostituto di Base64 o Base91 su file reali.
I tre alfabeti, e perché l'alfabeto è tutta la storia
I caratteri di un alfabeto sono una sequenza fissa, e il valore di un carattere è la sua posizione in quella sequenza. Spostare la sequenza cambia il significato di ogni carattere. Tre ordinamenti sono in uso diffuso, ed ecco lo stesso numero scritto in tre modi per ciascuno:
| Decimale | 0-9 poi A-Z poi a-z | 0-9 poi a-z poi A-Z | A-Z poi a-z poi 0-9 |
| 0 | 0 | 0 | A |
| 61 | z | Z | 9 |
| 62 | 10 | 10 | BA |
| 12.345 | 3D7 | 3d7 | DNH |
| 1.234.567.890 | 1LY7VK | 1ly7vk | BViHfU |
Leggete le ultime tre colonne come un unico alfabeto e formano uno schema coerente. Leggetele come intercambiabili e crolla, perché la decodifica è cieca all'alfabeto nel peggiore dei modi: ogni carattere dell'input appartiene a tutti e tre gli alfabeti, quindi un alfabeto sbagliato non produce alcun errore, solo un numero diverso.
| Un codice | Letto come 0-9 A-Z a-z | Letto come 0-9 a-z A-Z | Letto come A-Z a-z 0-9 |
| 3D7 | 12.345 | 13.957 | 211.665 |
| 1LY7VK | 1.234.567.890 | 1.624.950.792 | 48.723.527.772 |
Le maiuscole sono una versione più insidiosa della stessa trappola. La Base62 distingue le maiuscole in ogni ordinamento, quindi mettere in minuscolo un codice lo riscrive in silenzio: 1LY7VK è 1.234.567.890 nell'alfabeto con prima le cifre, mentre 1ly7vk è 1.624.950.792 nello stesso alfabeto — e per caso è 1.234.567.890 nell'alfabeto con cifre e poi minuscole, perché quell'ordinamento è esattamente quello con prima le cifre con i due casi delle lettere scambiati. Anche il carattere zero non è condiviso: i due ordinamenti con prima le cifre scrivono lo zero come 0, mentre quello con prima le lettere lo scrive come A, quindi quell'alfabeto non inizia affatto con una cifra.
La Base62 accanto alle altre codifiche
| Codifica | Bit per carattere | Dimensione rispetto all'input | Note |
| Base16 (esadecimale) | 4 | 200% | Due caratteri per byte, banalmente leggibile, nessun alfabeto da consultare. |
| Base32 | 5 | 160% | Non distingue le maiuscole e si può dettare a voce, la più dispendiosa del gruppo. |
| Base36 (0-9 a-z) | ~5,17 | ~155% | Solo cifre e lettere minuscole, quindi sopravvive a una conversione in minuscolo. 12345 è 9ix. |
| Base58 | ~5,86 | ~137% | Scelta per gli indirizzi, non per la densità: quattro caratteri simili vengono eliminati invece di essere ordinati. Vedi Base32 / Base58. |
| Base62 | ~5,95 | ~134% | Ogni carattere è una cifra o una lettera, quindi nulla viene mai sottoposto a escape. La densità si colloca tra Base58 e Base64. |
| Base64 | 6 | 133% | Il predefinito ovunque, al prezzo di +, / e =, i tre caratteri che costringono all'escape. Vedi Convertitore Base64. |
| Ascii85 / Base85 | 6,4 | 125% | 5 caratteri ogni 4 byte, ma divide per 85 e il suo alfabeto richiede le virgolette. Vedi Ascii85. |
| Base91 | ~6,5 | ~123% | La più densa di queste, e quella il cui output è meno sicuro da incollare senza escape. Vedi Base91. |
Le percentuali sono costi asintotici, arrotondati; i conteggi misurati dei caratteri per un input reale di 92 byte si trovano nella tabella delle dimensioni più in alto in questa pagina. In modalità intero il confronto va nel verso opposto, perché l'input è testo decimale e non byte: lì la Base62 è circa il 44% più corta delle cifre che sostituisce, e la Base36 circa il 36% più corta, ed è per questo che un codice ID di solito è Base62 o Base36 e non Base58.
Che cosa non è la Base62
- Non è uno standard. Non esiste una RFC né una specifica. Nessun organismo di standardizzazione ha mai definito la Base62, ed è per questo che l'alfabeto non è garantito e che questa pagina stampa tutti e tre gli ordinamenti invece di sceglierne uno in silenzio.
- Non è crittografia. È un cambio di base, nient'altro. Chiunque conosca l'alfabeto la inverte in un solo passaggio, e non c'è chiave, né salt, né alcuna forma di segretezza.
- Non è compressione. La modalità byte fa crescere i dati di circa un terzo. La modalità intero sembra compressione solo perché il testo decimale è un modo inefficiente di scrivere un numero.
- Non è insensibile alle maiuscole. La Base32 può essere messa in minuscolo e letta di nuovo; la Base62 no. Un codice che attraversa un sistema che normalizza le maiuscole è un codice corrotto.
- Non si auto-verifica. Non c'è un checksum né un carattere di controllo, quindi un solo carattere sbagliato dà un risultato dall'aspetto valido ma con un valore diverso. Se questo conta, l'ordinamento Bitcoin è dotato di checksum — vedi la sezione Base58Check di Base32 / Base58.
- Non ha lunghezza fissa. Il numero di caratteri cresce con il valore, quindi un contatore che parte da 1 e arriva a 627 passa da un carattere a otto. Riempia a una larghezza fissa quando serve una colonna stabile.
Trappole che mordono davvero
- L'alfabeto è la risposta a nove misteri su dieci. Se un altro strumento dà un codice diverso per lo stesso numero, confronti i due alfabeti carattere per carattere prima di sospettare un bug. La tabella sopra mostra lo stesso valore in tre alfabeti, e tutti e tre sono corretti.
- Un alfabeto sbagliato fallisce in silenzio. Non esiste un percorso d'errore:
3D7 si decodifica in 12.345, 13.957 o 211.665 a seconda di quale ordinamento si presume. Controlli il primo carattere, che è il più probabile riempimento di zeri, e controlli se l'alfabeto ha cifre o lettere in testa. - Gli zeri iniziali significano due cose diverse. In modalità intero
00012345 e 12345 sono lo stesso numero e si stampano allo stesso modo. In modalità byte uno zero iniziale è un dato, e si stampa come un carattere zero in più. Eliminarne uno cambia la stringa di byte. - La normalizzazione delle maiuscole distrugge un codice. Un indirizzo email, un nome host o un percorso Windows possono essere messi in minuscolo durante il trasporto. Un codice Base62 non sopravvive a questo, ed è la ragione per cui la Base36 esiste ancora.
- Gli input lunghi sono lenti, non solo grandi. La conversione è aritmetica sull'intero input in un colpo solo, quindi raddoppiare la lunghezza dell'input quadruplica il tempo. Questa pagina rifiuta gli input oltre i suoi limiti misurati invece di bloccarsi; la tabella delle dimensioni più in alto dà i numeri misurati.
- Una stringa Base62 non prova niente. Poiché quasi qualsiasi stringa di cifre e lettere si decodifica senza proteste, uno slug di URL arbitrario si decodificherà in qualche numero. Un codice ha significato solo se il sistema che lo ha emesso memorizza anche la corrispondenza.
Risposte rapide
«Perché un altro strumento Base62 dà un codice diverso per lo stesso numero?»
Perché l'alfabeto è diverso. La Base62 non ha una specifica con cui essere in disaccordo, quindi le implementazioni scelgono un ordinamento: cifre e maiuscole per prime, cifre e minuscole per prime, oppure lettere prima delle cifre. Cambi il selettore dell'alfabeto in cima a questa pagina per vedere tutte e tre le risposte affiancate.
«La Base62 è sicura in un URL?»
Sì, in ciascuno dei tre ordinamenti. Tutti i 62 caratteri sono lettere e cifre non sottoposte a escape, quindi nessuno di essi si espande in una tripletta percentuale in una query string, e nessuno termina un URL, un segmento di percorso o un attributo HTML. È l'intera ragione per cui i link brevi sono in Base62 e non in Base64.
«Quale è più piccola, Base62 o Base64?»
Per i byte la Base64 è di pochissimo più piccola: circa il 133% dell'input contro circa il 134%. Sul campione di 92 byte sopra i due pareggiano a 124 caratteri. Per i numeri decimali la Base62 accorcia il testo di circa il 44%, ed è lì che sta il guadagno pratico.
«Posso decodificare una stringa Base64 con questa pagina?»
No, e non vi dirà che è fallita. I due alfabeti si sovrappongono in tutti i 62 caratteri, quindi una stringa Base64 di solito è un input "valido" anche qui e si decodifica semplicemente in un numero diverso. Usi la Base64 per la Base64.
«Un codice Base62 ha una lunghezza massima?»
No, in teoria l'algoritmo non ha limiti. In pratica questa pagina si ferma a 4.096 cifre decimali, o 2.048 byte, perché l'aritmetica sottostante è quadratica e la scheda si bloccherebbe senza nulla sullo schermo che ne spieghi il motivo. La tabella dei limiti più in alto in questa pagina elenca i numeri misurati.
«Come faccio a sapere che il risultato di questa pagina è corretto?»
Prema Autotest. Esegue ogni esempio documentato, ogni lunghezza in byte da 0 a 64 e una serie di numeri decimali attraverso tutti e tre gli alfabeti, confrontando i valori restituiti con quelli immessi, e ricontrolla che tutti i 62 caratteri di ciascun alfabeto siano sicuri in un URL. Il pulsante Esempio confronta inoltre i suoi tre risultati con i valori registrati nel file dati di questa pagina, verificati con una seconda implementazione indipendente a grandi interi conservata negli strumenti di test di questo sito.
Standard e riconoscimenti
Non c'è uno standard da implementare qui: la Base62 è una convenzione, non una specifica, e i tre alfabeti stampati sopra sono quelli che compaiono nel software reale. Questa pagina la implementa con le routine a grandi interi del sito, scritte in aritmetica semplice su array di cifre così che nessuna dimensione sia mai limitata dal tipo numerico di JavaScript.
Il testo di questa pagina è stato scritto per questo sito. Ogni esempio svolto in questa pagina è stato prodotto dal codice stesso della pagina e poi verificato con una seconda implementazione indipendente che usa grandi interi nativi, conservata negli strumenti di test di questo sito; la stessa implementazione ha verificato le tabelle degli esempi e delle dimensioni nel file dati.