[GUIDE] 9 min read

[GUIDE] Qu'est-ce que le Base64 et comment fonctionne-t-il ?

Une explication pratique, à partir des premiers principes. Découvrez l'astuce de regroupement sur 6 bits derrière le Base64, pourquoi la sortie est 33 % plus grande, d'où vient le remplissage =, et quand l'utiliser.

April 2026 | fundamentals

// LA DÉFINITION EN UNE PHRASE

Le Base64 est une représentation textuelle de données binaires qui n'utilise que 64 caractères ASCII imprimables : A–Z, a–z, 0–9 et deux symboles (généralement + et /, avec = comme marqueur de remplissage). Telle est l'idée entière. Chaque triplet d'octets binaires est regroupé en quatre caractères Base64, et rien d'autre ne change.

Il s'agit d'un encodage, et non d'un chiffrement — n'importe qui peut l'inverser en quelques millisecondes. Le but n'est pas la confidentialité ; c'est le transport sûr. Le Base64 vous permet de placer des charges utiles binaires (images, certificats, fichiers PDF, clés cryptographiques) dans des endroits qui n'acceptent que du texte : attributs HTML, chaînes JSON, URL, corps d'e-mails, configurations YAML, colonnes TEXT de base de données, variables d'environnement.

// POURQUOI EN AVONS-NOUS BESOIN

Les canaux purement textuels suppriment ou altèrent les octets qu'ils ne reconnaissent pas. Une passerelle de messagerie qui ne comprend que l'ASCII 7 bits cassera le bit de poids fort de tout caractère non anglais. Un analyseur JSON rejettera les octets nuls intégrés. Une URL qui contient une espace littérale, un guillemet ou une esperluette est invalide tant que ces caractères ne sont pas encodés en pourcentage. Les normes SMTP des années 1990 supposaient que les corps de courrier seraient toujours du texte anglais simple — mais les utilisateurs voulaient aussi envoyer des photos et des feuilles de calcul.

Le Base64 résout ce problème en restreignant la sortie à 64 caractères qui traversent intacts tous les canaux de texte connus : 26 lettres majuscules, 26 lettres minuscules, 10 chiffres et deux symboles qui sont (a) imprimables, (b) non utilisés par les mécanismes d'échappement courants et (c) suffisamment distincts pour un aller-retour à travers l'ASCII. S'y ajoute un caractère de remplissage =, également sûr.

// L'ASTUCE DU REGROUPEMENT SUR 6 BITS

Voici le cœur mécanique du Base64 en une ligne : prenez l'entrée comme un flux de bits, découpez-la en morceaux de 6 bits, et recherchez chaque morceau dans un alphabet de 64 caractères.

Pourquoi 6 bits ? Parce que 2^6 = 64, de sorte que chaque bloc de 6 bits correspond exactement à un caractère de l'alphabet. Pourquoi pas 7 ou 8 bits ? 7 bits donnent 128 valeurs (trop — toutes ne sont pas imprimables), et 8 bits, c'est simplement du binaire brut à nouveau. 6 bits est le compromis idéal où chaque valeur possible possède un caractère lisible par l'humain.

Trois octets d'entrée = 24 bits = exactement quatre groupes de 6 bits = quatre caractères Base64. Ce rapport 3-pour-4 est fixe ; c'est la raison pour laquelle la sortie Base64 fait environ 4/3 de la taille de l'entrée, soit environ 33 % de plus.

// Worked example: encoding the 3 bytes 'Man' (77 97 110)
// ASCII:  M        a        n
// Binary: 01001101 01100001 01101110
// Re-group into 6-bit chunks:
//         010011 010110 000101 101110
// Decimal: 19     22     5      46
// Base64:  T      W      F      u
// Result:  'TWFu'  (stored as 4 ASCII bytes: 84 87 70 117)

// L'ALPHABET BASE64

La RFC 4648 §4 définit l'alphabet standard. Les positions 0–25 correspondent à A–Z, 26–51 à a–z, 52–61 à 0–9, la position 62 est +, et la position 63 est /.

La variante URL-safe (RFC 4648 §5, également appelée base64url) remplace + par - et / par _, afin que la sortie puisse être insérée sans danger dans des URL et des noms de fichiers sans échappement supplémentaire. Les deux variantes se décodent de manière identique si vous appliquez l'alphabet correspondant.

// Standard Base64 alphabet (index → character)
// 0–25:  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
// 26–51: a b c d e f g h i j k l m n o p q r s t u v w x y z
// 52–61: 0 1 2 3 4 5 6 7 8 9
// 62:    +       (or  -  in URL-safe)
// 63:    /       (or  _  in URL-safe)
// pad:   =

// D'OÙ VIENT LE REMPLISSAGE =

L'algorithme attend des tailles d'entrée qui soient des multiples de 3 octets (pour qu'elles se regroupent uniformément en 4 caractères Base64). Lorsque la longueur de l'entrée n'est pas un multiple de 3, un ou deux octets restent en surplus, ce qui n'est pas suffisant pour remplir le dernier groupe de 4 caractères en sortie. Le remplissage avec = indique combien d'octets manquaient.

• Longueur d'entrée mod 3 == 0 → aucun remplissage (par ex., 'Man' → 'TWFu').
• Longueur d'entrée mod 3 == 1 → deux caractères de remplissage (par ex., 'M' → 'TQ==').
• Longueur d'entrée mod 3 == 2 → un caractère de remplissage (par ex., 'Ma' → 'TWE=').

// Why 'M' becomes 'TQ==':
// Byte: M = 01001101                   (8 bits)
// Padded to 12 bits with zeros: 010011 010000
// Decimal: 19, 16  →  'T', 'Q'
// Output length must be multiple of 4 → add '==' padding
// Result: 'TQ=='
//
// When decoding, the decoder strips '==' and recovers the first 8 bits,
// discarding the trailing zero bits.

// LE SURCOÛT DE 33 % EST-IL EXACT ?

Proche, mais pas tout à fait. La formule exacte est ceil(n / 3) × 4 caractères pour une entrée d'octets de longueur n. Pour une entrée de 100 Ko, cela donne ceil(102400 / 3) × 4 = 136 534 caractères — 33,3 % de plus que 100 Ko. En pratique, une fois que vous ajoutez la compression gzip ou Brotli au niveau HTTP, le coût sur le fil se rapproche de 10 à 15 %, car le texte Base64 se compresse raisonnablement bien (bien que pas aussi bien que le binaire brut).

Pour les petites charges utiles, le remplissage compte : encoder 1 octet coûte 4 caractères (quatre fois la taille), et encoder 2 octets coûte aussi 4 caractères. Les minuscules chaînes Base64 paraissent donc étonnamment longues par rapport à leurs entrées.

// OÙ LE BASE64 EST UTILISÉ DANS LA VRAIE VIE

  • > Data URIs en HTML/CSS — intégrer des icônes et des logos en ligne : <img src="data:image/png;base64,…">
  • > Charges utiles JSON et GraphQL — API qui doivent transporter du binaire (téléversements de fichiers, miniatures) à l'intérieur d'un protocole textuel
  • > Jetons JWT — les trois parties séparées par des points d'un JWT sont des chaînes base64url
  • > Authentification HTTP Basic — username:password est encodé en Base64 dans l'en-tête Authorization (toujours non sécurisé sans TLS !)
  • > Courriers électroniques (MIME) — les pièces jointes sont encodées en Base64 pour survivre aux anciens serveurs SMTP 7 bits
  • > Certificats et clés au format PEM — le bloc -----BEGIN CERTIFICATE----- enveloppe un blob DER encodé en Base64
  • > Clés SSH — les lignes id_rsa.pub et authorized_keys sont des clés publiques encodées en Base64
  • > Colonnes TEXT de base de données — lorsque vous ne pouvez pas utiliser de type BLOB, le Base64 vous permet de stocker du binaire sous forme de texte
  • > Variables d'environnement — les valeurs des Secrets Kubernetes sont encodées en Base64 (mais NON chiffrées)
  • > Codes QR et liens magiques — courts jetons Base64 sûrs à intégrer dans des URL

// LE BASE64 N'EST PAS DU CHIFFREMENT

C'est la seule idée fausse la plus répandue. Le Base64 ne dissimule pas le contenu de vos données — il réécrit le binaire en texte à l'aide d'un mappage public et bien documenté. Un mot de passe encodé en Base64 sous la forme cGFzc3dvcmQ= est exactement aussi vulnérable que le texte en clair password ; n'importe qui peut le décoder en un seul appel de fonction. Traitez le Base64 comme vous traiteriez l'hexadécimal : c'est une représentation, pas une protection.

Si vous avez besoin de confidentialité, appliquez d'abord une vraie primitive cryptographique (AES-GCM, ChaCha20-Poly1305, age, PGP) au texte en clair, et ensuite encodez le texte chiffré en Base64 si vous devez le transporter via un canal textuel. L'étape Base64 est le dernier kilomètre, pas la couche de sécurité.

Les Secrets Kubernetes sont le piège canonique : Kubernetes stocke les valeurs secrètes encodées en Base64, ce qui les fait paraître vaguement protégées. Elles ne le sont pas — quiconque a un accès en lecture à l'espace de noms peut les inverser. La véritable protection des secrets nécessite des outils comme SealedSecrets, Vault, SOPS ou des intégrations KMS cloud-natives.

// UN ENCODAGE / DÉCODAGE RAPIDE DANS CHAQUE LANGAGE

// JavaScript (browser):
//   btoa('Hello')            → 'SGVsbG8='
//   atob('SGVsbG8=')         → 'Hello'
//   (btoa/atob only handle Latin-1; use TextEncoder for Unicode)
//
// Node.js:
//   Buffer.from('Hello').toString('base64')     → 'SGVsbG8='
//   Buffer.from('SGVsbG8=', 'base64').toString() → 'Hello'
//
// Python:
//   import base64
//   base64.b64encode(b'Hello')       → b'SGVsbG8='
//   base64.b64decode('SGVsbG8=')     → b'Hello'
//
// Go:
//   base64.StdEncoding.EncodeToString([]byte("Hello")) → "SGVsbG8="
//
// Ruby:
//   Base64.strict_encode64('Hello')   → 'SGVsbG8='
//
// Shell:
//   echo -n 'Hello' | base64          → 'SGVsbG8='
//   echo 'SGVsbG8=' | base64 -d        → 'Hello'

// ERREURS COURANTES À ÉVITER

  • > Encoder une chaîne URL-safe avec l'alphabet standard — le décodeur du destinataire rejettera le + et le /. Utilisez base64url lorsque la sortie va dans une URL, un cookie ou un nom de fichier.
  • > Double encodage — passer du texte déjà en Base64 par l'encodeur une seconde fois. Vérifiez toujours si les données sont déjà en Base64 avant de les encoder.
  • > Oublier l'UTF-8btoa('héllo') lève une exception dans le navigateur car é est hors Latin-1. Utilisez TextEncoder d'abord pour transformer la chaîne en octets.
  • > Incohérences de suppression du remplissage — base64url omet souvent le remplissage =. Si votre décodeur est strict, rajoutez le remplissage : input + '==='.slice((input.length + 3) % 4).
  • > Supposer que le Base64 est sécurisé — il ne l'est pas. Le chiffrement est distinct. Toujours.
  • > Utiliser Base64 pour d'énormes binaires — encoder un fichier de 500 Mo dans une seule chaîne épuisera la mémoire. Traitez-le plutôt en flux.
  • > Ligne enveloppée ou non — MIME/PEM enveloppent le Base64 sur 64 ou 76 colonnes avec \n. La plupart des autres contextes attendent une seule ligne. Supprimez ou insérez des sauts de ligne selon les besoins.

// LE BASE64 EN 30 SECONDES — L'AIDE-MÉMOIRE

  • > 64 caractères ASCII imprimables (A–Z, a–z, 0–9, +, /) plus le remplissage =
  • > 3 octets en entrée → 4 caractères en sortie (rapport fixe)
  • > La sortie est environ 33 % plus grande que l'entrée
  • > Réversible : c'est un encodage, pas un chiffrement
  • > Utilisez base64url (remplacez + → -, / → _) pour les URL et les noms de fichiers
  • > Remplissez les entrées courtes avec 1 ou 2 caractères = pour que la longueur de sortie soit un multiple de 4
  • > Pour le texte Unicode : encodez d'abord la chaîne en octets UTF-8, puis encodez ces octets en Base64
  • > Décodable par la bibliothèque standard de tous les langages courants
  • > Sûr dans les HTML, JSON, URL, e-mails et fichiers PEM
  • > Pas sûr en tant que couche de sécurité — associez-le toujours à un vrai chiffrement pour les données sensibles

// PROCHAINES ÉTAPES

Maintenant que vous connaissez la mécanique, essayez notre encodeur Base64 ou notre décodeur Base64 et inspectez la sortie caractère par caractère. Pour les charges utiles URL-safe, passez à base64url. Pour les images, consultez image → Base64.

Articles approfondis connexes :
Base64 URL-safe vs standard — quand utiliser chaque alphabet
Base64 pour UTF-8 et Unicode — éviter le piège de btoa()
Base64 en JavaScript & Node.js — atob, btoa, Buffer
Base64 vs Base64URL vs Base32 — tableau de comparaison