Base32

Encode du texte ou de l’hexadécimal en Base32 ou base32hex, remplissage et casse au choix, et le décode, avec la ligne et la colonne d’un caractère intrus.

Entrée
Sortie
IJXW42TPOVZA====

Des octets en trente-deux caractères, et les chiffres laissés de côté

Le Base32 écrit des octets sous forme de texte, en trente-deux caractères qui représentent chacun cinq bits, si bien que chaque tranche de cinq octets — quarante bits — devient huit caractères. Hello fait cinq octets et s’écrit JBSWY3DP. Choisissez « Décoder » et collez du Base32, et la page rend les octets qu’il représente : sous forme de texte, ou en hexadécimal si vous réglez « Octets en » sur « Hexadécimal ».

La RFC 4648, qui le définit, utilise les vingt-six lettres majuscules et les chiffres 2 à 7. La RFC donne la raison pour laquelle 0 et 1 manquent : quiconque manipule le texte peut facilement prendre 0 pour O, et 1 pour l ou I, et l’alphabet garde donc les lettres et laisse ces deux chiffres de côté. En plus des lettres, il lui faut six chiffres, et les six qu’il prend sont 2 à 7 : 8 et 9 n’y figurent donc pas non plus. Quand elle décode dans cet alphabet, la page refuse un 0, un 1, un 8 ou un 9 là où il se trouve, plutôt que de lire un 0 comme un O ou un 1 comme un I : la RFC permet à un décodeur de les lire ainsi, et dit que par défaut il ne devrait pas le faire.

La casse ne fait pas partie de la valeur. La RFC 4648 a conçu le Base32 pour du texte qui doit se lire sans tenir compte de la casse, si bien que jbswy3dp est Hello tout comme JBSWY3DP. La RFC écrit son alphabet en majuscules, et cette page aussi, sauf si vous activez « minuscules ». La lecture ignore aussi les caractères d’espacement, où qu’ils se trouvent, sauts de ligne compris, si bien qu’un Base32 coupé en groupes ou réparti sur plusieurs lignes se lit comme s’il était écrit d’un seul tenant.

Le remplissage, et les longueurs que prend le Base32

Le nombre d’octets tombe rarement sur un multiple de cinq. Un à quatre octets restés à la fin prennent deux, quatre, cinq ou sept caractères, et la RFC 4648 complète ce dernier groupe jusqu’à huit avec des = : six, quatre, trois ou un. Ainsi f s’écrit MY======, fo MZXQ====, foo MZXW6=== et foob MZXW6YQ=, tandis que fooba, cinq octets, remplit exactement ses huit caractères sous la forme MZXW6YTB.

Comptés par huit, les caractères qui précèdent un éventuel = laissent donc toujours un reste de 0, 2, 4, 5 ou 7, et jamais de 1, 3 ou 6, puisqu’aucun nombre d’octets ne laisse ces restes-là ; la page refuse un tel texte à son dernier caractère plutôt que de le lire comme quelque chose de plus court. Le remplissage ne dit rien que la longueur ne dise déjà, si bien que la page lit le Base32 dont le remplissage a été omis — JBUQ est Hi tout comme JBUQ==== — et ne refuse le remplissage que là où il est présent et faux : un = au milieu, avec encore du texte après lui, ou un mauvais nombre de = à la fin, et le refus dit alors combien il en faut.

Quand vous encodez, l’interrupteur « Remplissage » décide si les = sont écrits. Il est activé au départ, parce que la RFC 4648 demande un remplissage sauf si la spécification qui l’utilise dit autrement, et plusieurs le font : le Key Uri Format, qui décrit l’otpauth:// URI d’un QR code 2FA, dit que le remplissage d’un secret devrait être omis, et les enregistrements NSEC3 et IPFS n’en écrivent pas. L’interrupteur « minuscules », à côté, écrit les lettres en minuscules ; les chiffres et le = n’ont pas de casse à changer. Les deux interrupteurs ne sont là que pendant l’encodage, puisque la lecture accepte toutes leurs combinaisons.

D’autres outils lisent moins que cette page. GNU coreutils écrit le Base32 avec base32, et le base32hex, le second alphabet, avec basenc --base32hex ; le module base64 de Python a une fonction pour chacun. Tous écrivent ce que cette page écrit à son ouverture, avec remplissage et en majuscules. Mais base32 -d refuse un Base32 dont le remplissage manque ou dont les lettres sont en minuscules, et le b32decode de Python refuse lui aussi l’un et l’autre, ne lisant les minuscules que si on lui passe casefold=True :

# Écrire : l’alphabet par défaut, puis l’autre
printf 'Hi' | base32                          # JBUQ====
printf 'Hi' | basenc --base32hex              # 91KG====

# Relire : avec remplissage, puis sans remplissage, puis en minuscules
printf 'JBUQ====' | base32 -d                 # Hi
printf 'JBUQ' | base32 -d                     # base32: invalid input
printf 'jbuq====' | base32 -d                 # base32: invalid input

# La même chose dans un script
import base64
base64.b32encode(b'Hi')                       # b'JBUQ===='
base64.b32hexencode(b'Hi')                    # b'91KG===='
base64.b32decode('JBUQ')                      # binascii.Error: Incorrect padding
base64.b32decode('jbuq====', casefold=True)   # b'Hi'

Deux alphabets : base32 et base32hex

La RFC 4648 définit un second alphabet, le base32hex : les chiffres 0 à 9, puis les lettres A à V, si bien que ses caractères se suivent dans l’ordre des valeurs qu’ils représentent, de 0 pour zéro à V pour trente et un. Cela lui donne une propriété qui manque au premier, et que la RFC signale : comparé caractère par caractère, son texte se trie dans l’ordre des octets qu’il représente. L’octet 00 s’écrit AA====== en base32 et 00====== en base32hex, et l’octet FF, 74====== et VS====== ; si l’on trie ces textes, le base32 place FF en premier, puisque les chiffres passent avant les lettres, tandis que le base32hex garde les octets dans l’ordre.

Les enregistrements NSEC3 de DNSSEC l’utilisent. Le nom d’un enregistrement commence par le hachage d’un nom de domaine, écrit en base32hex sans remplissage, et la RFC 5155 note qu’ainsi écrits, les noms hachés se trient dans le même ordre que les hachages par leur valeur. Dans sa propre zone d’exemple, example a pour hachage 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom. Avec base32hex choisi, la page lit ces 32 caractères comme les 20 octets du hachage ; avec base32 choisi, elle refuse le 0 — et un avis dit que le texte se lit en entier en base32hex, à côté d’un bouton qui y fait passer.

Comme les mêmes octets donnent un texte différent dans chacun — Hi s’écrit JBUQ==== en base32 et 91KG==== en base32hex —, l’alphabet que vous choisissez vaut dans les deux sens, et la page ne le change jamais à votre place. Quand un texte que vous décodez contient un caractère que l’alphabet choisi n’a pas, ou se termine par des bits excédentaires qui ne sont pas nuls, qu’expliquent les questions ci-dessous, alors que l’autre alphabet le lit en entier tel qu’un encodeur l’écrirait, un avis le signale à côté d’un bouton qui fait changer d’alphabet ; l’alphabet ne change que si vous appuyez sur ce bouton ou si vous le choisissez vous-même. Un texte que les deux lisent proprement, comme ABCDEFGH, est lu dans celui qui est choisi, puisque rien en lui ne dit lequel était voulu.

Où l’on rencontre le Base32 : secrets 2FA, adresses onion et IPFS

C’est en Base32 que le Key Uri Format écrit le secret dont découlent les codes d’une application 2FA. Ce format décrit l’otpauth:// URI que peut contenir un QR code de configuration : le paramètre secret de l’URI est en Base32, et son remplissage devrait être omis. Collez un tel secret en majuscules ou en minuscules, en groupes séparés par des espaces ou répartis sur plusieurs lignes, avec ou sans = — un trait d’union entre les groupes est refusé là où il se trouve —, ou collez l’URI entier, et la page lit le secret qu’il contient et le signale. Ce que veulent dire les autres paramètres de l’URI, et la façon dont un secret devient les codes qu’affiche une application, relèvent du Débogueur de codes TOTP / 2FA : son guide explique l’URI et ses paramètres, et sa page calcule les codes. L’étiquette et l’émetteur que contient l’URI sont encodés en pourcent, comme le demande le Key Uri Format, et l’Encodeur / décodeur d’URL les lit.

Une adresse onion de la version 3 de Tor est elle aussi du Base32. Ses 56 caractères avant .onion sont le Base32 de 35 octets : la clé publique de 32 octets du service, une somme de contrôle de deux octets et un octet de version, 03. La spécification de Tor écrit ses adresses d’exemple en minuscules, et 35 octets remplissent des groupes entiers, si bien qu’il n’y a pas de remplissage à omettre. Collez les 56 caractères sans .onion, réglez « Octets en » sur « Hexadécimal », et le dernier octet se lit 03.

IPFS écrit ses identifiants de contenu, les CID, en Base32 par défaut à partir de la version 1 : en minuscules et sans remplissage, après une lettre, b, qui ne fait pas partie du Base32 mais le désigne — le préfixe de multibase, qu’on retire avant de décoder le reste. Ainsi bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi, l’exemple que donne la documentation même d’IPFS, est refusé ici tel quel, comme une longueur qu’aucun octet ne produit ; sans son b, il se lit comme 36 octets, le CID binaire, qui commence par 01 pour sa version.

Un secret 2FA, ce sont des octets, pas du texte

Le secret d’exemple du Key Uri Format est JBSWY3DPEHPK3PXP, et ce document en détaille la valeur sous forme de dix octets : les caractères de Hello!, puis DE AD BE EF. Ses huit premiers caractères, JBSWY3DP, sont Hello à eux seuls. Décodé ici avec « Octets en » sur « Texte », le réglage par défaut de la page, il donne Hello!, puis U+07AD — DE AD forment par hasard un caractère, un signe de l’écriture thâna — et ensuite deux U+FFFD, chacun tenant lieu d’une séquence qui n’est pas du texte. Un avis sous le résultat compte les séquences remplacées, dit que la première commence à l’octet 9, dont les bits débutent dans le caractère de la ligne 1, colonne 13, le 3, et dit que les octets ne sont peut-être pas du texte du tout.

Un vrai secret est fait d’octets aléatoires, qui forment rarement du texte, si bien que, décodé comme du texte, il donne un éparpillement de caractères égarés et de U+FFFD qui ne vous dit pas si le secret est le bon. C’est à cela que sert « Octets en » réglé sur « Hexadécimal ». Choisissez ce réglage, ou appuyez sur le bouton à côté de l’avis, et le même secret s’affiche en entier sous la forme 48 65 6C 6C 6F 21 DE AD BE EF : les octets eux-mêmes, ce que garde un serveur et ce à partir de quoi chaque code est calculé. La page ne passe jamais d’elle-même à l’hexadécimal, si bien que ce qui est à l’écran est toujours ce que vous avez choisi.

Dans l’autre sens, c’est le même choix, fait pendant l’encodage. Une clé qu’un serveur garde en hexadécimal est faite d’octets : choisissez « Encoder », réglez « Octets en » sur « Hexadécimal » et collez-la — espacée ou accolée, avec 0x devant les octets, sous forme de tableau de nombres ou de vidage hexadécimal disposé comme l’écrivent hexdump -C ou xxd —, et la page écrit le Base32 qu’accepte une application d’authentification. 48656C6C6F21DEADBEEF donne JBSWY3DPEHPK3PXP, le secret ci-dessus ; dix octets remplissent des groupes entiers, et une clé dont ce n’est pas le cas, comme une clé de seize octets, sort suivie de = à moins que vous ne désactiviez le remplissage, comme le demande le Key Uri Format. De l’hexadécimal collé par erreur pendant le décodage — un nombre pair de chiffres hexadécimaux et rien d’autre que des caractères d’espacement, sous une forme que l’encodage sait lire comme des octets — fait apparaître un avis disant qu’il ressemble à de l’hexadécimal, à côté d’un bouton qui passe à son encodage. Et pendant le décodage, « Télécharger » enregistre les octets eux-mêmes dans un fichier nommé bytes.bin.

Base32 ou Base64, et pourquoi pas l’alphabet de Crockford

Le Base64 fait le même travail avec soixante-quatre caractères, quatre pour trois octets, ce qui rend son texte plus long d’un tiers que les octets, là où celui du Base32 l’est de trois cinquièmes. En échange, le Base64 renonce à ignorer la casse : son alphabet tient les majuscules et les minuscules pour des valeurs différentes, avec en plus + et /, si bien que SGk= vaut Hi et sgk= deux autres octets. Le Base32 convient au texte qui passe par quelque chose qui ignore la casse, ou qu’une personne lit sur un écran et tape sur un autre. Quand du Base64 collé ici contient un + ou un /, qu’aucun Base32 n’écrit, et a d’un bout à l’autre la forme du Base64, il est refusé avec un avis disant qu’il ressemble à du Base64 et un lien vers l’outil Base64, qui lit le Base64 comme du texte.

D’autres alphabets de trente-deux caractères existent, et cette page propose les deux de la RFC 4648 et aucun autre. L’un d’eux, celui de Douglas Crockford, garde les dix chiffres au complet et laisse de côté I, L, O et U, et c’est lui qu’utilise le format ULID. Crockford l’a défini pour écrire des nombres, et, appliqué à des octets, cet alphabet donne deux réponses : les seize octets 00 à 0F, empaquetés cinq bits à la fois comme la RFC 4648 empaquette les octets, donnent 000G40R40M30E209185GR38E1W, et lus comme un seul nombre de 128 bits, comme on lit les vingt-six caractères d’un ULID, ils donnent 00041061050R3GG28A1C60T3GF. Une page qui écrirait des octets dans cet alphabet choisirait l’une des deux réponses à votre place, sans que vous le voyiez.

Questions fréquentes

Pourquoi mon secret décodé affiche-t-il U+FFFD ?
Parce qu’un secret 2FA est fait d’octets aléatoires, et que des octets aléatoires forment rarement du texte UTF-8. Avec « Octets en » sur « Texte », la page écrit chaque séquence qui n’est pas du texte sous la forme U+FFFD, le caractère de remplacement, et un avis dit combien il y en a eu et où commence la première, en donnant l’octet où elle commence ainsi que la ligne et la colonne du caractère où commencent les bits de cet octet. Les octets eux-mêmes restent intacts : le bouton à côté de l’avis les affiche en hexadécimal, et « Télécharger » les enregistre. Un U+FFFD qui se trouve vraiment dans un texte, les octets EF BF BD, est lu comme du texte et n’est pas compté.
Que veut dire « une longueur qu’aucun octet ne produit » ?
Comptés par huit, les caractères d’un Base32, une fois les = mis de côté, laissent un reste de 0, 2, 4, 5 ou 7, quels que soient les octets ; un texte qui laisse 1, 3 ou 6 ne peut donc représenter aucune suite d’octets, et la page le refuse à son dernier caractère. Un tel texte n’a pas été écrit ainsi par un encodeur : quelque chose s’est perdu ou ajouté sur son chemin jusqu’à vous. JBSWY3DPEHPK3P, le secret du Key Uri Format privé de deux caractères, est refusé à cet endroit. Une coupure peut aussi tomber sur une longueur que des octets produisent bel et bien, et le texte se lit alors comme moins d’octets — JBSWY3DPEHPK3PX comme neuf —, ce que la page ne peut remarquer que là où les bits excédentaires du dernier caractère ne sont pas nuls, comme c’est le cas pour ce X. Une coupure au bout d’un groupe entier de huit ne laisse rien à remarquer.
Que sont les bits excédentaires, et pourquoi la page dit-elle que les miens ne sont pas nuls ?
Cinq bits par caractère et huit par octet tombent rarement juste, si bien qu’à moins que les octets ne viennent par cinq, le dernier caractère porte un à quatre bits qu’aucun octet ne contient, et un encodeur les écrit à zéro. MZXW6YQ= et MZXW6YR= valent tous deux foob : les trois derniers bits de Q sont 000 et ceux de R, 001, et seul le premier est ce qu’écrit un encodeur. La page lit les deux, et pour le second, son avis nomme le R, l’endroit où il se trouve et le Q qu’un encodeur écrit à cet endroit. Des bits excédentaires non nuls signifient que le texte n’est pas tel qu’un encodeur l’a écrit : il a pu être coupé, retouché à la main ou écrit dans l’autre alphabet, et ce dernier cas, la page le vérifie pour vous.
Le Base32 est-il un chiffrement ?
Non. Le Base32 change la façon dont les octets s’écrivent, et rien d’autre : n’importe qui peut le décoder, et tout décodeur qui suit la RFC 4648 retrouve les mêmes octets dans le même alphabet. Un secret 2FA écrit en Base32 est le secret lui-même, si bien que quiconque voit la clé de configuration détient votre second facteur.
Ce que je colle est-il envoyé à un serveur ?
Non. Les deux sens s’exécutent dans cette page, sur votre propre appareil : rien de ce que vous collez — un secret, un texte ou de l’hexadécimal — n’est téléversé, et le fichier qu’enregistre « Télécharger » est créé dans votre navigateur à partir des octets qui s’y trouvent déjà.

Outils connexes

  • Base64

    Le Base64 écrit quatre caractères pour trois octets, là où le Base32 en écrit huit pour cinq, et en Base64 la casse d’une lettre fait partie de sa valeur : abc s’écrit YWJj sur cette page-là, et YWJJ s’y lit abI.

  • Débogueur de codes TOTP / 2FA

    Générez et déboguez des codes 2FA, avec la dérivation complète.

  • Encodeur / décodeur d’URL

    Encode en pourcent une valeur ou une URL entière, et inversement.

  • Échappement de chaînes JSON

    Échappez du texte pour une chaîne JSON, ou relisez-en une échappée.