Ce qu’est Base64 et pourquoi il existe
Base64 est une manière d’écrire des données binaires quelconques avec seulement 64 caractères ASCII imprimables : A–Z, a–z, 0–9, + et /, plus = pour le remplissage. C’est un encodage : n’importe qui peut l’inverser sans clé. Il ne cache rien (plus de détails dans encodage ou chiffrement).
Le but est de faire passer des octets intacts par des canaux qui ne transportent que du texte. Un fichier PNG contient des octets comme 0x00, 0x1A et 0x89 qu’un canal texte peut supprimer, convertir ou traiter comme un code de contrôle. Écrit en Base64, le même fichier devient iVBORw0KGgo..., qui traverse sans modification les e-mails, le JSON, le XML, les URL (avec la variante URL-safe), les terminaux et le copier-coller.
La définition actuelle est la RFC 4648. Des spécifications plus anciennes, pour l’e-mail MIME (RFC 2045) et les certificats PEM, décrivent le même alphabet avec des règles supplémentaires sur la longueur des lignes. Un résumé des variantes se trouve sur la page des normes Base64.
Pourquoi l’e-mail en avait besoin
Les débuts de l’e-mail reposaient sur du texte ASCII 7 bits. Les relais de messagerie de l’époque pouvaient supprimer le bit de poids fort de chaque octet, couper les longues lignes et réécrire les fins de ligne, ce qui est sans conséquence pour une lettre et fatal pour un fichier ZIP. MIME avait besoin d’un moyen de faire passer n’importe quelle pièce jointe dans ce tuyau, avec un alphabet capable de survivre à chaque système du parcours.
C’est ce qui a dicté le choix des 64 caractères de Base64. Les lettres et les chiffres sont identiques en ASCII et dans presque tous les anciens jeux de caractères, + et / sont presque aussi sûrs, et aucun n’est un caractère de contrôle ou un espace. 64 est aussi la plus grande puissance de deux qu’on puisse remplir à partir de cet ensemble sûr, et une puissance de deux garde l’arithmétique sur les bits simple. Le prix est la taille : 6 bits utiles par caractère de 8 bits, donc une sortie égale aux 4/3 de l’entrée, plus le remplissage.
Le problème des 8 bits a pratiquement disparu des serveurs de messagerie modernes, mais la même contrainte réapparaît partout où des données binaires doivent tenir dans un format texte. JSON n’a pas de type binaire, et les attributs HTML, le CSS et les en-têtes HTTP sont tous du texte : Base64 reste donc la manière par défaut d’y placer des octets.
L’algorithme : 3 octets en entrée, 4 caractères en sortie
Base64 travaille sur des blocs de 24 bits. C’est le plus petit nombre qui soit à la fois multiple de 8 (un octet) et de 6 (un caractère Base64) : 3 octets correspondent donc exactement à 4 caractères.
Pour chaque bloc :
- Prenez 3 octets et écrivez-les sous forme de 24 bits à la suite.
- Découpez ces 24 bits en quatre groupes de 6 bits.
- Lisez chaque groupe comme un nombre de 0 à 63.
- Cherchez ce nombre dans l’alphabet et écrivez le caractère correspondant.
L’alphabet est une table fixe. L’indice 0 correspond à A, 25 à Z, 26 à a, 51 à z, 52 à 0, 61 à 9, 62 à + et 63 à /. La table complète se trouve sur la page de l’alphabet Base64.
| Plage | Caractères | Exemple |
|---|---|---|
| 0–25 | A–Z | 19 → T |
| 26–51 | a–z | 46 → u |
| 52–61 | 0–9 | 52 → 0 |
| 62 | + | |
| 63 | / |
Le décodage suit les mêmes étapes à l’envers : chaque caractère donne 6 bits, quatre caractères forment 24 bits, et ces 24 bits se découpent en 3 octets.
Exemple détaillé : « Man » devient TWFu
L’exemple classique utilise le texte ASCII Man. En ASCII, M vaut 77, a vaut 97 et n vaut 110.
| M | a | n | |
|---|---|---|---|
| Décimal | 77 | 97 | 110 |
| Binaire | 01001101 | 01100001 | 01101110 |
Mettez les bits bout à bout : 010011010110000101101110. Découpez-les maintenant par groupes de 6 bits au lieu de 8 :
| Groupe de 6 bits | 010011 | 010110 | 000101 | 101110 |
|---|---|---|---|---|
| Valeur | 19 | 22 | 5 | 46 |
| Caractère | T | W | F | u |
Man s’encode donc en TWFu. Remarquez qu’aucun caractère de sortie ne correspond à une lettre de l’entrée. Le W est construit à partir des 4 derniers bits de M et des 2 premiers bits de a. C’est pourquoi modifier un octet de l’entrée modifie deux caractères de la sortie, et pourquoi on ne peut pas lire du Base64 à l’œil nu, même quand l’entrée est du simple texte.
Vous pouvez le vérifier dans n’importe quel shell :
echo -n Man | base64
# TWFu
Sans -n, echo ajoute un octet de saut de ligne, et Man\n s’encode en TWFuCg==.
Quand l’entrée n’est pas un multiple de 3 : le remplissage
Les données réelles ont rarement une longueur divisible par 3. Le dernier bloc contient alors 1 ou 2 octets, et Base64 le complète avec des bits à zéro et des signes =.
Deux octets restants, « Ma » → TWE=. Deux octets font 16 bits. On ajoute deux bits à zéro pour atteindre 18, soit trois groupes de 6 bits :
| Groupe de 6 bits | 010011 | 010110 | 000100 | (aucun) |
|---|---|---|---|---|
| Valeur | 19 | 22 | 4 | |
| Caractère | T | W | E | = |
Le troisième groupe est formé de 0001, venu de a, suivi des deux zéros ajoutés : il vaut 4, soit E. Un = remplace le quatrième caractère manquant.
Un octet restant, « M » → TQ==. Un octet fait 8 bits. On ajoute quatre bits à zéro pour atteindre 12, soit deux groupes : 010011 (19, T) et 010000 (16, Q). Deux signes = complètent le bloc.
Le nombre de = indique donc combien d’octets contenait le dernier bloc : aucun signifie 3, un signifie 2, deux signifient 1. Il n’y a jamais de troisième =, car un bloc sans aucun octet restant n’existe pas. Le guide du remplissage explique quand on peut omettre = et comment le rétablir.
import base64
for s in [b"Man", b"Ma", b"M"]:
print(s, base64.b64encode(s))
# b'Man' b'TWFu'
# b'Ma' b'TWE='
# b'M' b'TQ=='
Le texte doit d’abord devenir des octets
Base64 encode des octets. Le texte ne devient une suite d’octets qu’une fois l’encodage de caractères choisi, et ce choix change le résultat. Le mot café fait 5 octets en UTF-8 (é en prend deux) et s’encode en Y2Fmw6k=. En Latin-1, il fait 4 octets et s’encode en Y2Fm6Q==.
C’est l’origine d’un piège bien connu en JavaScript. La fonction btoa() du navigateur traite chaque caractère d’une chaîne comme un octet, ce qui correspond au comportement Latin-1 :
btoa("café"); // "Y2Fm6Q==" (Latin-1, not UTF-8)
btoa("café ✓"); // throws InvalidCharacterError
Pour obtenir du Base64 UTF-8 en JavaScript, convertissez d’abord en octets avec TextEncoder, ou utilisez Buffer dans Node.js. La page de code JavaScript montre les méthodes qui fonctionnent, et Uint8Array.toBase64() présente la méthode intégrée plus récente. L’encodeur Base64 de ce site utilise UTF-8 par défaut et vous laisse choisir un autre jeu de caractères.
Où l’on rencontre Base64
- Les pièces jointes d’e-mails. Chaque pièce jointe d’un fichier
.emlbrut est un bloc Base64 coupé à 76 caractères. Voir Base64 dans l’e-mail. - Les data URI.
data:image/png;base64,iVBORw0KGgo...intègre une image directement dans du HTML ou du CSS. La question de savoir si c’est une bonne idée est traitée dans les performances des data URI. - HTTP Basic Auth. L’en-tête
Authorization: Basic dXNlcjpwYXNzn’est queuser:passen Base64. - Les JWT. Les trois parties séparées par des points d’un JSON Web Token sont en Base64URL. Voir Base64 dans les JWT.
- Les fichiers PEM. Les certificats et les clés entre les lignes
-----BEGIN ...-----sont du Base64 de données DER binaires. - Les API et la configuration. Les Secrets Kubernetes, les métadonnées cloud, les payloads de webhooks et de nombreuses API JSON transportent des fichiers ou des blobs binaires sous forme de chaînes Base64.
Avec le temps, on reconnaît les blobs à leurs premiers caractères : iVBORw0KGgo est un PNG, JVBERi0 un PDF, /9j/ un JPEG et eyJ du JSON qui commence par {". La page des préfixes Base64 courants en liste davantage. Pour voir ce que contient un blob, l’outil Base64 en fichier détecte le format et en affiche un aperçu dans votre navigateur.
Collez du Base64 et voyez le texte ou les octets qu'il contient. Tout se passe localement dans votre navigateur.
FAQ
Base64 est-il une forme de compression ?
Non. Il agrandit toujours les données : 3 octets en entrée deviennent 4 caractères en sortie, soit environ 33 % de plus. Voir le surcoût de taille de Base64 pour la formule exacte.
Pourquoi s'appelle-t-il Base64 ?
Chaque caractère de sortie porte une valeur parmi 64 possibles, soit 6 bits d’information. Le nom vient de la taille de l’alphabet, de la même façon que l’hex est la base 16.
Peut-on encoder n'importe quelles données en Base64 ?
Oui. L’algorithme travaille sur des octets et ne se soucie pas de leur signification : texte, images, PDF, clés et archives compressées s’encodent tous de la même façon. Le texte doit d’abord être converti en octets avec un encodage de caractères, généralement UTF-8.
La sortie Base64 contient-elle parfois des espaces ou des sauts de ligne ?
Pas le Base64 simple de la RFC 4648. Certains formats le coupent en lignes, par exemple l’e-mail MIME à 76 caractères et les fichiers PEM à 64, et la plupart des décodeurs ignorent ces espaces.