Charger un fichier
  1. base64hub
  2. Apprendre Base64
  3. Surcoût de taille
Référence

Le surcoût de taille de Base64 : la formule exacte

Chaque groupe de 3 octets devient 4 caractères : Base64 est donc un tiers plus gros que son entrée, plus 2 caractères de remplissage au maximum et les éventuels sauts de ligne.

La formule

Pour une entrée de n octets, le Base64 avec remplissage (le défaut dans la RFC 4648) fait exactement :

length = 4 × ceil(n / 3)

Sans remplissage, comme le Base64URL des JWT, il fait :

length = ceil(4n / 3)

La différence entre les deux correspond au nombre de signes =, soit 0, 1 ou 2 selon n mod 3. Le guide du remplissage explique d’où ils viennent.

Dans l’autre sens, une chaîne Base64 avec remplissage de longueur L se décode en :

bytes = 3 × L / 4 − (number of trailing "=")

Ainsi, TWFu fait 3 octets, TWE= 2 et TQ== 1. Supprimez les espaces et les sauts de ligne avant de compter. Le calculateur de taille Base64 fonctionne dans les deux sens, sauts de ligne et préfixes de data URI compris.

En code :

import base64, math, os
for n in [1, 2, 3, 100, 1000]:
    data = os.urandom(n)
    assert len(base64.b64encode(data)) == 4 * math.ceil(n / 3)
const b64Len = (n) => 4 * Math.ceil(n / 3);
const rawLen = (s) => (s.length * 3) / 4 - (s.endsWith("==") ? 2 : s.endsWith("=") ? 1 : 0);
b64Len(1000);    // 1336
rawLen("TWE=");  // 2

Pourquoi le surcoût est de 33 %

Un octet compte 8 bits. Un caractère Base64 porte 6 bits de données, puisqu’il fait partie de 64 = 2⁶ symboles, mais il est stocké comme un octet ASCII de 8 bits. Chaque octet de sortie contient donc 6 bits utiles, et la sortie doit faire 8/6 = 4/3 de l’entrée. Cela fait 33,3 % de plus, et c’est un plancher absolu : aucune implémentation de Base64 ne peut faire mieux sans abandonner l’alphabet. (Le regroupement des bits est détaillé étape par étape dans le fonctionnement de Base64.)

Pour les petites entrées, le remplissage dégrade le ratio, puisque la sortie arrive toujours par blocs de 4. Un octet devient 4 caractères, soit une augmentation de 300 %. À partir de quelques centaines d’octets, le remplissage devient négligeable et le ratio se stabilise à 4/3.

Il existe des encodages texte plus denses. Base85 stocke 4 octets en 5 caractères (25 % de surcoût), et Base91 fait un peu mieux. Ils sont moins largement pris en charge et leurs alphabets contiennent des caractères qui posent problème dans certains contextes. La comparaison se trouve dans Base64, hex, Base32, Base58 et Base85 comparés.

Sauts de ligne : MIME, PEM et outils en ligne de commande

Certains formats coupent le Base64 en lignes, et les fins de ligne comptent dans la taille.

FormatLongueur de ligneFin de ligneSurcoût total
Base64 simple (RFC 4648)pas de découpageaucune33,3 %
E-mail MIME (RFC 2045)76CRLF (2 octets)36,8 %
GNU base64, encodebytes de Python76LF (1 octet)35,1 %
Certificats et clés PEM64LF35,4 %

Le chiffre de MIME vient de 4/3 × 78/76 : chaque tranche de 76 caractères de Base64 apporte 2 octets de CRLF en plus. Avec L = 4 × ceil(n / 3), la taille avec un CRLF après chaque ligne, y compris la dernière, est :

mime_length = L + 2 × ceil(L / 76)

Chaque ligne complète de 76 caractères contient exactement 57 octets d’entrée : c’est pourquoi les encodeurs MIME traitent les données par blocs de 57 octets. Plus d’informations sur l’e-mail dans Base64 dans les e-mails, et l’encodeur Base64 MIME produit une sortie découpée.

Table des tailles

Calculée avec les formules ci-dessus et vérifiée avec le module base64 de Python.

EntréeBase64 avec remplissageSans remplissageMIME (76 + CRLF)Surcoût (avec remplissage)
1 octet426300 %
2 octets436100 %
3 octets44633,3 %
10 octets16141860 %
57 octets76767833,3 %
100 octets13613414036 %
1 000 octets1 3361 3341 37233,6 %
1 Kio (1 024)1 3681 3661 40433,6 %
1 Mo (10⁶)1 333 3361 333 3341 368 42433,3 %
1 Mio (1 048 576)1 398 1041 398 1021 434 89833,3 %
10 Mio13 981 01613 981 01414 348 93833,3 %
25 Mo (25 × 10⁶)33 333 33633 333 33434 210 53033,3 %

La dernière ligne correspond au cas de l’e-mail. Les limites de taille SMTP (l’extension SIZE, RFC 1870) portent sur le message tel que transmis, encodage compris : un fichier de 25 Mo devient environ 34,2 Mo sur le réseau et ne passera pas la limite d’un serveur fixée à 25 Mo. Certains fournisseurs expriment plutôt leurs limites en taille de pièce jointe : vérifiez comment le vôtre compte.

L’effet de la compression

La compression interagit de deux façons avec Base64, et l’ordre compte.

Compressez avant d’encoder chaque fois que vous maîtrisez les deux extrémités. Le Base64 de données compressées représente 4/3 d’un nombre plus petit. Pour le texte de la licence GPL-3 (35 149 octets), nous avons mesuré avec zlib de Node.js, au niveau 9 de gzip :

Chaîne de traitementTaille
Texte brut35 149
Base64 seul46 868
Base64, puis gzip17 465
gzip, puis Base6416 124
gzip seul12 091

L’outil Gzip + Base64 applique la chaîne « gzip, puis Base64 » dans le navigateur.

La compression au transport récupère l’essentiel du surcoût pour les données binaires. Si une chaîne Base64 circule dans une réponse HTTP compressée avec gzip ou Brotli, le compresseur ramène les caractères de 6 bits vers 6 bits chacun. Pour 1 Mio d’octets aléatoires, le Base64 est monté à 1 398 104 caractères ; compressé avec gzip, il faisait 1 053 023 octets (0,4 % au-dessus des données brutes) et Brotli l’a ramené à 1 048 805. Les mêmes données avec des sauts de ligne MIME donnaient 1 088 689 octets avec gzip : les CRLF coûtent donc environ 3,4 % même après compression.

Pour le texte, c’est différent. Base64 casse les répétitions dont dépendent les compresseurs : du texte en Base64 se compresse donc bien moins bien que le texte lui-même, 17 465 contre 12 091 octets dans le tableau ci-dessus. L’article data URI et performances donne des mesures pour PNG, JPEG, WOFF2 et SVG.

Limites des URL, des en-têtes et des cookies

Base64 fait grossir tout ce que vous mettez dans une URL, un en-tête ou un cookie, et ces trois emplacements ont des limites.

  • Les URL. La RFC 9110 recommande que les émetteurs et les destinataires prennent en charge des URI d’au moins 8 000 octets. De nombreux serveurs s’arrêtent à peu près là par défaut : nginx alloue des tampons d’en-tête de 8 Ko pour la ligne de requête, et LimitRequestLine d’Apache vaut 8 190 octets par défaut. Les URL plus longues échouent en général avec 414 URI Too Long. En Base64URL, cela laisse de la place pour environ 6 000 octets de données, moins le reste de l’URL.
  • Les en-têtes. Les mêmes tampons de serveur s’appliquent à chaque ligne d’en-tête, ce qui compte pour les longs JWT dans les en-têtes Authorization: Bearer ... et pour les identifiants Basic Auth volumineux.
  • Les cookies. La RFC 6265 demande aux navigateurs de prendre en charge au moins 4 096 octets par cookie, nom et attributs compris. Cela représente environ 3 Ko de données une fois encodées en Base64.

Si un contenu Base64 approche de l’une de ces limites, envoyez-le plutôt dans le corps d’une requête, ou stockez-le côté serveur et transmettez un identifiant.

Calculer la taille Base64

Saisissez un nombre d'octets ou collez une chaîne pour voir les tailles encodée et décodée, avec ou sans sauts de ligne.

Calculateur de taille

FAQ

De combien Base64 est-il plus gros que le fichier d'origine ?

D’environ 33,3 % pour tout ce qui dépasse quelques octets. Avec les sauts de ligne MIME (76 caractères plus CRLF), c’est environ 36,8 %.

Comment calculer la taille d'origine à partir d'une chaîne Base64 ?

Prenez la longueur sans les espaces, multipliez-la par 3/4 et soustrayez le nombre de signes = à la fin. Par exemple, TWE= donne 4 × 3/4 − 1 = 2 octets.

Pourquoi une entrée de 1 octet produit-elle 4 caractères ?

Avec remplissage, Base64 produit toujours des blocs complets de 4 caractères. Un octet remplit 2 caractères et les 2 autres sont des = : les toutes petites entrées ont donc un surcoût relatif bien plus élevé.

Peut-on rendre Base64 plus compact ?

Compressez les données avant de les encoder, par exemple avec gzip, et supprimez le remplissage si le destinataire l’accepte. Base64 a lui-même un ratio fixe ; des encodages texte plus denses comme Base85 existent, mais sont moins largement pris en charge.

Continuer la lecture