Les 64 caractères
Base64 lit l’entrée par blocs de 3 octets (24 bits) et les découpe en quatre nombres de 6 bits. Chaque nombre, de 0 à 63, est un index dans cette table. L’ordre est fixé par la RFC 4648 : majuscules de 0 à 25, minuscules de 26 à 51, chiffres de 52 à 61, puis + et /. La dernière colonne donne le code ASCII du caractère, c’est-à-dire ce qui est réellement stocké ou transmis.
| Index | 6 bits | Base64 | Base64URL | Code ASCII |
|---|---|---|---|---|
| 0 | 000000 | A | A | 0x41 |
| 1 | 000001 | B | B | 0x42 |
| 2 | 000010 | C | C | 0x43 |
| 3 | 000011 | D | D | 0x44 |
| 4 | 000100 | E | E | 0x45 |
| 5 | 000101 | F | F | 0x46 |
| 6 | 000110 | G | G | 0x47 |
| 7 | 000111 | H | H | 0x48 |
| 8 | 001000 | I | I | 0x49 |
| 9 | 001001 | J | J | 0x4A |
| 10 | 001010 | K | K | 0x4B |
| 11 | 001011 | L | L | 0x4C |
| 12 | 001100 | M | M | 0x4D |
| 13 | 001101 | N | N | 0x4E |
| 14 | 001110 | O | O | 0x4F |
| 15 | 001111 | P | P | 0x50 |
| 16 | 010000 | Q | Q | 0x51 |
| 17 | 010001 | R | R | 0x52 |
| 18 | 010010 | S | S | 0x53 |
| 19 | 010011 | T | T | 0x54 |
| 20 | 010100 | U | U | 0x55 |
| 21 | 010101 | V | V | 0x56 |
| 22 | 010110 | W | W | 0x57 |
| 23 | 010111 | X | X | 0x58 |
| 24 | 011000 | Y | Y | 0x59 |
| 25 | 011001 | Z | Z | 0x5A |
| 26 | 011010 | a | a | 0x61 |
| 27 | 011011 | b | b | 0x62 |
| 28 | 011100 | c | c | 0x63 |
| 29 | 011101 | d | d | 0x64 |
| 30 | 011110 | e | e | 0x65 |
| 31 | 011111 | f | f | 0x66 |
| 32 | 100000 | g | g | 0x67 |
| 33 | 100001 | h | h | 0x68 |
| 34 | 100010 | i | i | 0x69 |
| 35 | 100011 | j | j | 0x6A |
| 36 | 100100 | k | k | 0x6B |
| 37 | 100101 | l | l | 0x6C |
| 38 | 100110 | m | m | 0x6D |
| 39 | 100111 | n | n | 0x6E |
| 40 | 101000 | o | o | 0x6F |
| 41 | 101001 | p | p | 0x70 |
| 42 | 101010 | q | q | 0x71 |
| 43 | 101011 | r | r | 0x72 |
| 44 | 101100 | s | s | 0x73 |
| 45 | 101101 | t | t | 0x74 |
| 46 | 101110 | u | u | 0x75 |
| 47 | 101111 | v | v | 0x76 |
| 48 | 110000 | w | w | 0x77 |
| 49 | 110001 | x | x | 0x78 |
| 50 | 110010 | y | y | 0x79 |
| 51 | 110011 | z | z | 0x7A |
| 52 | 110100 | 0 | 0 | 0x30 |
| 53 | 110101 | 1 | 1 | 0x31 |
| 54 | 110110 | 2 | 2 | 0x32 |
| 55 | 110111 | 3 | 3 | 0x33 |
| 56 | 111000 | 4 | 4 | 0x34 |
| 57 | 111001 | 5 | 5 | 0x35 |
| 58 | 111010 | 6 | 6 | 0x36 |
| 59 | 111011 | 7 | 7 | 0x37 |
| 60 | 111100 | 8 | 8 | 0x38 |
| 61 | 111101 | 9 | 9 | 0x39 |
| 62 | 111110 | + | - | 0x2B |
| 63 | 111111 | / | _ | 0x2F |
| remplissage | – | = | souvent omis | 0x3D |
Deux plages valent la peine d’être retenues. Tous les caractères de A à P (0 à 15) commencent par les bits 00, et tous ceux de w à / (48 à 63) par 11. Cela suffit pour décoder un caractère de tête quand vous vérifiez un préfixe à la main. Un exemple détaillé du découpage des bits se trouve dans le fonctionnement de Base64.
L’ordre de l’alphabet n’est pas l’ordre ASCII. En ASCII, + et / viennent en premier, puis les chiffres, les majuscules et enfin les minuscules. Trier des chaînes Base64 ne trie donc pas les octets sous-jacents : +A== (l’octet F8) passe avant AA== (l’octet 00). Si vous avez besoin de valeurs encodées qui se trient comme les octets bruts, utilisez base32hex de la RFC 4648 ou simplement l’hexadécimal.
L’alphabet URL-safe
+ et / ont tous deux un sens particulier dans les URL. + est décodé en espace dans les chaînes de requête et les données de formulaire, et / sépare les segments du chemin. Base64URL, défini à la section 5 de la RFC 4648, conserve les index 0 à 61 et remplace les deux derniers :
| Index | Base64 | Base64URL |
|---|---|---|
| 62 | + | - |
| 63 | / | _ |
Tout le reste, y compris la disposition des bits, est identique : passer de l’un à l’autre revient à remplacer des caractères et à ajouter ou retirer le remplissage. Les JWT, de nombreux jetons d’API et les identifiants compatibles avec les noms de fichiers utilisent Base64URL, le plus souvent sans =. L’encodeur Base64URL le produit directement. La comparaison complète se trouve dans Base64 ou Base64URL.
Le caractère de remplissage
= (ASCII 0x3D) ne fait pas partie de l’alphabet de 64 caractères et n’encode jamais de données. Il sert uniquement à compléter le dernier groupe de 4 caractères quand la longueur de l’entrée n’est pas un multiple de 3 :
- 1 octet restant : 2 caractères de données plus
==. - 2 octets restants : 3 caractères de données plus
=. - Aucun octet restant : pas de remplissage.
Une chaîne avec remplissage a donc toujours une longueur multiple de 4, et vous ne verrez jamais ===. Sans remplissage, la longueur divisée par 4 laisse un reste de 0, 2 ou 3, jamais 1. Le guide du remplissage explique quand = peut être omis et comment le rétablir.
Quels caractères apparaissent où
Quelques régularités découlent directement de la disposition des bits. Elles ont été vérifiées par force brute sur toutes les valeurs d’octets concernées.
Avant ==, vous ne verrez que A, Q, g ou w. Avec un octet restant, le deuxième caractère porte 2 bits de données suivis de 4 bits à zéro : son index vaut donc 0, 16, 32 ou 48. Avant un seul =, le troisième caractère se termine par 2 bits à zéro et fait donc partie de 16 caractères : A E I M Q U Y c g k o s w 0 4 8. Tout autre caractère à cette position signale un encodage non canonique, que les décodeurs stricts rejettent.
Des octets aléatoires utilisent les 64 caractères à parts égales. Chaque groupe de 6 bits de données aléatoires suit une distribution uniforme : les données chiffrées, les clés et les fichiers compressés donnent une répartition des caractères plate. Une répartition déséquilibrée indique que les données sont du texte ou ont une structure.
Du texte ASCII ne place jamais en tête les minuscules de g à z, les chiffres, + ou /. Le premier caractère de chaque groupe de 4 contient les 6 bits de poids fort d’un octet. En ASCII 7 bits, le bit de poids fort vaut 0, donc ce caractère est toujours compris entre A et f (index 0 à 31). Dans SGVsbG8gd29ybGQh (Hello world!), les groupes commencent par S, b, d et b.
Dans le Base64 d’un texte ASCII, + et / sont rares. Pour des octets inférieurs à 0x80, + ne peut apparaître qu’en quatrième position d’un groupe, quand le troisième octet est > ou ~. / ne peut y apparaître que si cet octet est ? ou le caractère de contrôle DEL. Voilà pourquoi Hi?> s’encode en SGk/Pg== et <b> en PGI+.
Les suites de A sont des octets nuls, les suites de / des 0xFF. AAAA correspond à trois octets 00, //// à trois octets FF. De longues séries de A sont typiques des formats binaires creux, du texte UTF-16 (Hello donne SABlAGwAbABvAA==) et des champs de longueur au début des clés SSH. D’autres motifs reconnaissables figurent dans les préfixes Base64 courants.
Autres alphabets Base64
Plusieurs systèmes ont gardé l’idée de 64 caractères pour 6 bits, mais avec d’autres caractères :
| Variante | Alphabet dans l’ordre des index | Où |
|---|---|---|
| Standard | A-Z a-z 0-9 + / | RFC 4648, MIME, PEM, la plupart des API |
| URL-safe | A-Z a-z 0-9 - _ | RFC 4648 section 5, JWT |
| Noms de boîtes IMAP | A-Z a-z 0-9 + , | UTF-7 modifié de la RFC 3501 |
| bcrypt | . / A-Z a-z 0-9 | hachages de mots de passe $2a$, $2b$, $2y$ |
| crypt(3) | . / 0-9 A-Z a-z | MD5-crypt $1$, SHA-crypt $5$ et $6$, DES crypt |
| xxencode | + - 0-9 A-Z a-z | Ancienne messagerie Unix et Usenet |
| uuencode | ASCII 32 à 95 (de l’espace à _), souvent avec ` pour 0 | Ancienne messagerie Unix et Usenet |
- IMAP remplace
/par,parce que/sert couramment de séparateur de hiérarchie dans les noms de boîtes aux lettres. Un dossier nomméEntwürfeest stocké sous la formeEntw&APw-rfe. - bcrypt place
.et/en tête et garde les lettres avant les chiffres. Ses sels et ses hachages sont en Base64 dans cet alphabet, sans remplissage : c’est pourquoi un décodeur standard en tire des octets erronés. - crypt(3) utilise
./0-9A-Za-z, qui suit l’ordre ASCII. Il range aussi les bits en partant du poids faible : même avec l’alphabet converti, un décodeur standard ne retrouvera pas les octets du hachage. - uuencode et xxencode sont antérieurs à MIME. Les outils uuencode et xxencode lisent et écrivent les deux formats.
Pour les encodages dont l’alphabet a une autre taille, comme Base32, Base58 et Base85, voir Base64, hex, Base32, Base58 et Base85 comparés. Les termes employés ici sont définis dans le glossaire.
FAQ
Combien de caractères compte l'alphabet Base64 ?
64 caractères pour les données : 26 lettres majuscules, 26 minuscules, 10 chiffres, + et /. Le signe de remplissage = est un 65e symbole qui ne porte jamais de données.
Quelle est la valeur Base64 de la lettre A ?
A correspond à l’index 0, en binaire 000000. B vaut 1, Z 25, a 26, z 51, 0 52, 9 61, + 62 et / 63.
Quels caractères Base64URL change-t-il ?
Deux seulement : + (index 62) devient - et / (index 63) devient _. Le remplissage est en général supprimé aussi. Convertissez avec Base64 en Base64URL.