Qu’est-ce que le Base62 ?
Le Base62 est une façon d’écrire un nombre avec les seuls caractères qui survivent à un collage n’importe où : les dix chiffres, les 26 lettres majuscules et les 26 lettres minuscules. Ni ponctuation, ni espace, ni caractère de remplissage, rien qui doive être échappé avant d’entrer dans une URL, un nom de fichier, un cookie ou une clé de base de données. Dix plus 26 plus 26 font 62, et c’est d’où vient le nom.
La version en 30 secondes : le nombre 12345 s’écrit 3D7, et 1234567890 s’écrit 1LY7VK. Le chemin inverse est la même opération à l’envers, et il exige l’alphabet exact qui a produit le code : un autre alphabet transforme les mêmes six caractères en un autre nombre, sans aucun message d’erreur.
Cette page accomplit deux tâches liées, et la différence entre elles compte plus que toute autre chose ici :
- Mode entier traite l’entrée comme un nombre. Un identifiant décimal comme
1234567890 devient 1LY7VK, et les zéros de tête de l’entrée ne font pas partie de la valeur : ils ne reviennent donc pas.
- Mode octets traite l’entrée comme une suite d’octets. Les octets sont lus comme un seul très grand entier en gros-boutiste, puis divisés par 62 : c’est la même arithmétique, appliquée à une autre quantité. Ici, le nombre d’octets nuls de tête survit, avec un caractère zéro par octet nul.
D’où vient le 62, et ce qu’il coûte
62 n’est pas une puissance de deux, et ce seul fait façonne tout le reste. Les encodages familiers se construisent en découpant l’entrée en groupes de bits fixes : 4 bits donnent un caractère hexadécimal, 6 bits un caractère Base64, 5 bits un caractère Base32. Le Base62 ne peut pas faire ainsi, car aucun nombre entier de bits ne correspond à un caractère de 62 valeurs — 5 bits ne désignent que 32 valeurs, 6 bits en désignent 64. Le Base62 passe donc par l’arithmétique : il lit l’entrée entière comme un seul entier, puis l’écrit en base 62.
Un caractère porte alors log2(62) = 5,954 bits, très proche des 6 du Base64 ; en mode décimal, un caractère remplace log62(10) = 1,792 chiffre décimal. Quelques conséquences utiles à connaître avant de choisir une longueur :
| Longueur du code | Valeurs qu’il peut désigner | En pratique |
| 4 caractères | 624 = 14 776 336 | Suffisant pour un compteur qui reste sous huit chiffres, et tient dans l’équivalent d’un numéro de téléphone. |
| 6 caractères | 626 = 56 800 235 584 | La forme habituelle d’un code d’identifiant. Un identifiant décimal à dix chiffres tient en six caractères. |
| 7 caractères | 627 = 3 521 614 606 208 | Au-delà de la plage d’un compteur 32 bits de deux ordres de grandeur, dans la largeur d’un slug de lien court. |
| 11 caractères | 6211 = 52 036 560 683 837 093 888 | Plus que 264 = 18 446 744 073 709 551 616, si bien qu’un nombre complet de 64 bits tient en onze caractères. |
Dans l’autre sens, 1 000 chiffres décimaux demandent environ 558 caractères, et 4 096 chiffres décimaux en demandent 2 285. Le gain est réel, mais borné : le Base62 raccourcit un nombre décimal d’environ 44%, et il ne bat jamais les encodages imprimables les plus denses, car 5,954 bits par caractère est tout simplement inférieur à 6,4 ou 6,5.
Mode entier : ce qui arrive aux zéros de tête
Un entier a une seule forme écrite canonique, et elle commence par le caractère zéro de l’alphabet, soit 0 dans les deux ordres chiffres-d’abord et A dans l’ordre lettres-d’abord. Tout ce qui se trouve à gauche du premier caractère significatif est du remplissage, et le remplissage ne fait pas partie d’une valeur : 00012345 et 12345 donnent tous deux 3D7. Si une largeur fixe est voulue — par exemple un code de sept caractères qui doit s’aligner dans une colonne —, la case Compléter le résultat à une largeur fixe de la page répète le caractère zéro jusqu’à atteindre cette largeur : ainsi 12345 sur une largeur de 7 s’écrit 00003D7 dans l’alphabet chiffres-d’abord, et AAAADNH dans l’alphabet lettres-d’abord. Le remplissage est cosmétique : ces caractères de tête n’ajoutent rien à la valeur, et décoder l’une ou l’autre chaîne redonne 12345, car 0 × 626 et 0 × 625 valent tous deux zéro, quel que soit le caractère qui épelle le zéro.
Décoder une chaîne complétée fonctionne donc aussi, et la page indique combien des premiers caractères étaient des caractères zéro : la différence entre « le code fait sept caractères » et « la valeur n’en demandait que trois » n’est ainsi jamais un mystère.
Mode octets : la même arithmétique sur une suite d’octets
Le mode octets lit les octets de l’entrée comme un entier gros-boutiste — toute la suite d’octets est traitée comme un seul nombre, quelle que soit sa longueur — et écrit ce nombre en base 62. Comme un octet contient 8 bits et qu’un caractère en porte 5,954, le mode octets n’est pas une compression : il exige environ 134% de la taille de l’entrée, un peu plus que les 133% du Base64. Sur l’échantillon de 92 octets du tableau des tailles plus haut, 92 octets s’écrivent en 124 caractères Base62, et le Base64 en écrit aussi 124 (123 avant son remplissage =). Le Base62 perd face au Base64 en densité et gagne en sûreté des caractères, un compromis que font délibérément tous les liens courts et codes d’invitation.
Les octets nuls de tête sont préservés, et c’est facile à rater dans les deux sens. Deux octets nuls suivis de 0x01 s’impriment 001 dans l’alphabet chiffres-d’abord, et AAB dans l’alphabet lettres-d’abord, car les caractères de tête épellent zéro, à raison d’un par octet nul. Une suite d’un seul 0x00 s’imprime en un seul caractère 0, et une suite d’un seul 0x01 s’imprime 1. C’est le seul endroit où le mode octets et le mode entier semblent différents tout en exécutant le même algorithme.
Le prix de tout cela est que le mode octets hérite de la complexité quadratique de l’arithmétique : 1 024 octets sont estimés à environ un tiers de seconde, et 2 048 octets à environ 1,3 seconde, les mêmes valeurs que celles du tableau des limites plus haut. C’est pourquoi le mode octets est ici plafonné à 2 048 octets en sortie et à 2 048 caractères au retour — 2 048 octets s’impriment en environ 2 751 caractères, si bien qu’environ 1 520 octets est la charge utile la plus grande qui survit à un aller-retour sur cette page — et pourquoi le mode octets de cette page est une référence pour les petites valeurs, et non un substitut au Base64 ou au Base91 pour de vrais fichiers.
Les trois alphabets, et pourquoi l’alphabet est toute l’histoire
Les caractères d’un alphabet forment une suite fixe, et la valeur d’un caractère est sa position dans cette suite. Déplacer la suite change le sens de chaque caractère. Trois ordres sont largement utilisés, et voici le même nombre écrit dans chacun d’eux :
| Décimal | 0-9 puis A-Z puis a-z | 0-9 puis a-z puis A-Z | A-Z puis a-z puis 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 |
Lisez les trois dernières colonnes comme un seul alphabet, et c’est un schéma cohérent. Lisez-les comme interchangeables, et tout s’effondre, car le décodage est aveugle à l’alphabet de la pire façon possible : chaque caractère de l’entrée appartient aux trois alphabets, si bien qu’un mauvais alphabet ne produit aucune erreur, seulement un autre nombre.
| Un code | Lu comme 0-9 A-Z a-z | Lu comme 0-9 a-z A-Z | Lu comme 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 |
La casse est une seconde version, plus tranchante, du même piège. Le Base62 est sensible à la casse dans les trois ordres : mettre un code en minuscules le réécrit donc en silence. 1LY7VK vaut 1 234 567 890 dans l’alphabet chiffres-d’abord, tandis que 1ly7vk vaut 1 624 950 792 dans ce même alphabet — et il vaut par hasard 1 234 567 890 dans l’alphabet chiffres-puis-minuscules, car cet ordre n’est précisément l’ordre chiffres-d’abord avec les deux casses de lettres échangées. Le caractère zéro n’est pas non plus partagé : les deux ordres chiffres-d’abord écrivent zéro 0, tandis que l’ordre lettres-d’abord l’écrit A, si bien que cet alphabet ne commence pas du tout par un chiffre.
Le Base62 face aux autres encodages
| Encodage | Bits par caractère | Taille par rapport à l’entrée | Remarques |
| Base16 (hex) | 4 | 200% | Deux caractères par octet, immédiatement lisibles, sans alphabet à consulter. |
| Base32 | 5 | 160% | Insensible à la casse et sûr pour la dictée, le plus gaspilleur du groupe. |
| Base36 (0-9 a-z) | ~5,17 | ~155% | Chiffres et lettres minuscules seulement : il survit donc à un traitement en minuscules. 12345 s’écrit 9ix. |
| Base58 | ~5,86 | ~137% | Choisi pour les adresses, non pour la densité : quatre caractères qui se ressemblent sont retirés au lieu d’être ordonnés. Voir Base32 / Base58. |
| Base62 | ~5,95 | ~134% | Chaque caractère est un chiffre ou une lettre, donc rien n’est jamais échappé. La densité se situe entre celle du Base58 et celle du Base64. |
| Base64 | 6 | 133% | La valeur par défaut partout, au prix de +, / et =, les trois caractères qui imposent un échappement. Voir le convertisseur Base64. |
| Ascii85 / Base85 | 6,4 | 125% | 5 caractères pour 4 octets, mais il divise par 85 et son alphabet exige des guillemets. Voir Ascii85. |
| Base91 | ~6,5 | ~123% | Le plus dense de ceux-ci, et celui dont la sortie est la moins sûre à coller sans échappement. Voir Base91. |
Les pourcentages sont des coûts asymptotiques, arrondis ; les nombres de caractères mesurés pour une entrée réelle de 92 octets figurent dans le tableau des tailles plus haut sur cette page. En mode entier, la comparaison s’inverse, car l’entrée est du texte décimal et non des octets : là, le Base62 est environ 44% plus court que les chiffres qu’il remplace, et le Base36 environ 36% plus court, ce qui explique pourquoi un code d’identifiant est normalement en Base62 ou en Base36, et non en Base58.
Ce que le Base62 n’est pas
- Ce n’est pas une norme. Il n’existe ni RFC ni spécification. Aucun organisme de normalisation n’a jamais défini le Base62, c’est pourquoi l’alphabet n’est pas garanti et pourquoi cette page affiche les trois ordres au lieu d’en choisir un en silence.
- Ce n’est pas du chiffrement. C’est un changement de base, rien de plus. Quiconque connaît l’alphabet l’inverse en une seule passe ; il n’y a ni clé, ni sel, ni secret d’aucune sorte.
- Ce n’est pas de la compression. Le mode octets fait grossir les données d’environ un tiers. Le mode entier n’a l’air de compresser que parce que le texte décimal est une façon inefficace d’écrire un nombre en premier lieu.
- Ce n’est pas insensible à la casse. Le Base32 peut être mis en minuscules puis relu ; le Base62 ne le peut pas. Un code qui transite par un système qui normalise la casse est un code corrompu.
- Ce n’est pas auto-vérifiant. Il n’y a ni somme de contrôle ni caractère de contrôle : un seul caractère erroné donne un résultat d’apparence valide, mais une autre valeur. Si cela compte, l’ordre Bitcoin est accompagné d’une somme de contrôle — voir la section Base58Check de Base32 / Base58.
- Ce n’est pas de longueur fixe. Le nombre de caractères croît avec la valeur : un compteur qui part de 1 et atteint 627 passe donc d’un caractère à huit. Complétez jusqu’à une largeur fixe lorsqu’il faut une colonne stable.
Pièges qui mordent vraiment
- L’alphabet est la réponse à neuf mystères sur dix. Si un autre outil donne un code différent pour le même nombre, comparez les deux alphabets caractère par caractère avant de soupçonner un bogue. Le tableau ci-dessus montre la même valeur dans trois alphabets, et les trois sont corrects.
- Un mauvais alphabet échoue en silence. Il n’existe pas de chemin d’erreur pour cela :
3D7 se décode en 12 345, 13 957 ou 211 665 selon le seul ordre supposé. Vérifiez le premier caractère, le plus susceptible d’être un zéro de remplissage, et vérifiez si l’alphabet commence par des chiffres ou par des lettres.
- Les zéros de tête signifient deux choses différentes. En mode entier,
00012345 et 12345 sont le même nombre et s’impriment de façon identique. En mode octets, un octet nul de tête est une donnée et s’imprime comme un caractère zéro supplémentaire. Retirer l’un de ces caractères modifie la suite d’octets.
- La normalisation de la casse détruit un code. Une adresse e-mail, un nom d’hôte ou un chemin Windows peut être mis en minuscules en transit. Un code Base62 ne peut pas y survivre, et c’est la raison pour laquelle le Base36 existe encore.
- Les entrées longues sont lentes, pas seulement volumineuses. La conversion est une arithmétique portant sur l’entrée entière d’un seul coup : doubler la longueur de l’entrée quadruple le temps. Cette page refuse les entrées au-delà de ses limites mesurées au lieu de se figer ; le tableau des tailles plus haut donne les valeurs mesurées.
- Une chaîne Base62 ne prouve rien. Comme presque toute chaîne de chiffres et de lettres se décode sans protester, un slug d’URL quelconque se décodera en un nombre. Un code n’a de sens que si le système qui l’a émis conserve aussi la correspondance.
Réponses rapides
« Pourquoi un autre outil Base62 donne-t-il un code différent pour le même nombre ? »
Parce que l’alphabet diffère. Le Base62 n’a aucune spécification pour trancher, si bien que les implémentations choisissent un ordre : chiffres et majuscules d’abord, chiffres et minuscules d’abord, ou lettres avant chiffres. Changez le sélecteur d’alphabet en haut de cette page pour voir les trois réponses côte à côte.
« Le Base62 est-il sûr dans une URL ? »
Oui, dans chacun des trois ordres. Les 62 caractères sont tous des lettres et des chiffres non échappés : aucun ne se développe en triplet de pourcentage dans une requête, et aucun ne termine une URL, un segment de chemin ou un attribut HTML. C’est la raison entière pour laquelle les liens courts sont en Base62 et non en Base64.
« Lequel est le plus petit, du Base62 ou du Base64 ? »
Pour des octets, le Base64 est très légèrement plus petit : environ 133% de l’entrée contre environ 134%. Sur l’échantillon de 92 octets ci-dessus, les deux se départagent à 124 caractères. Pour les nombres décimaux, le Base62 raccourcit le texte d’environ 44%, et c’est là que se situe le gain pratique.
« Puis-je décoder une chaîne Base64 avec cette page ? »
Non, et il ne signalera pas l’échec. Les deux alphabets se recouvrent sur les 62 caractères, si bien qu’une chaîne Base64 est en général une entrée « valide » ici aussi, et se décode simplement en un autre nombre. Utilisez le Base64 pour le Base64.
« Un code Base62 a-t-il une longueur maximale ? »
Non, en théorie l’algorithme n’a pas de borne. En pratique, cette page s’arrête à 4 096 chiffres décimaux, soit 2 048 octets, car l’arithmétique sous-jacente est quadratique et l’onglet se figerait sans rien à l’écran pour l’expliquer. Le tableau des limites plus haut sur cette page donne les valeurs mesurées.
« Comment savoir que le résultat de cette page est juste ? »
Appuyez sur Autotest. Il exécute chaque exemple documenté, chaque longueur d’octets de 0 à 64 et une série de nombres décimaux dans les trois alphabets, en comparant les valeurs renvoyées à celles qui ont été saisies, et il revérifie que les 62 caractères de chaque alphabet sont tous sûrs dans une URL. Le bouton Exemple compare en outre ses trois résultats aux valeurs consignées dans le fichier de données de cette page, qui ont été vérifiées par une seconde implémentation indépendante à grands entiers conservée dans l’outillage de test de ce site.
Normes et crédits
Il n’y a pas de norme à implémenter ici : le Base62 est une convention, non une spécification, et les trois alphabets affichés plus haut sont ceux qu’on trouve dans les logiciels réels. Cette page l’implémente avec les routines de grands entiers du site, écrites en arithmétique simple sur des tableaux de chiffres, afin qu’aucune taille ne soit jamais limitée par le type nombre de JavaScript.
Le texte de cette page a été écrit pour ce site. Chaque exemple travaillé a été produit par le code de la page elle-même, puis vérifié par une seconde implémentation indépendante utilisant de grands entiers natifs, conservée dans l’outillage de test de ce site ; cette même implémentation a vérifié les tableaux d’exemples et de tailles du fichier de données.