Base64: Quelle est la pire augmentation possible de l'utilisation de l'espace?

168

Si un serveur a reçu une chaîne en base64 et voulait vérifier sa longueur avant la conversion, disons qu'il voulait toujours autoriser le tableau d'octets final à 16 Ko. Quelle peut être la taille d'un tableau d'octets de 16 Ko lorsqu'il est converti en une chaîne Base64 (en supposant un octet par caractère)?

Champ Bryan
la source

Réponses:

245

Base64 code chaque ensemble de trois octets en quatre octets. De plus, la sortie est complétée pour être toujours un multiple de quatre.

Cela signifie que la taille de la représentation en base 64 d'une chaîne de taille n est:

ceil(n / 3) * 4

Ainsi, pour un tableau de 16 Ko, la représentation en base 64 sera ceil (16 * 1024/3) * 4 = 21848 octets de long ~ = 21,8 Ko.

Une approximation approximative serait que la taille des données est augmentée à 4/3 de l'original.

R. Martinho Fernandes
la source
Faut-il ajouter 2 à la longueur ou non?
vIceBerg
@vIceBerg, cela dépend si vous utilisez ceildes floatnombres ou simplement des intnombres. (et non ceil)
Bryan Field
7
Je suppose que la façon la plus simple de mettre cela est d'ajouter 1/3 de la taille d'origine.
mvmn
1
Dans l'exemple que vous avez proposé, afficher le résultat dans le même ordre de mesure augmenterait un peu la qualité de la réponse (21,3 Ko au lieu de 21848 octets).
Ivan De Paz Centeno
36

De Wikipedia

Notez que pour une entrée de n octets, la sortie sera (n + 2 - ((n + 2)% 3)) / 3 * 4 octets de long, de sorte que le nombre d'octets de sortie par octet d'entrée converge vers 4/3 ou 1.33333 pour grand n.

Donc 16 ko * 4/3 donne très peu plus de 21,3 ko, soit 21848 octets, pour être exact.

J'espère que cela t'aides

Binaire Worrier
la source
11

16 Ko correspond à 131 072 bits. Base64 emballe les tampons 24 bits en quatre caractères 6 bits chacun, vous auriez donc 5 462 * 4 = 21 848 octets.

Chris Heald
la source
5

Puisque la question portait sur la pire augmentation possible, je dois ajouter qu'il y a généralement des sauts de ligne à environ 80 caractères. Cela signifie que si vous enregistrez des données encodées en base64 dans un fichier texte sous Windows, il ajoutera 2 octets, sous Linux 1 octet pour chaque ligne.

L'augmentation par rapport au codage réel a été décrite ci-dessus.

Ciel de Zsolt
la source
3
N'est-ce pas le cas extrême où 1 octet source devient 4 octets base64, donc une augmentation 4x? Tout matériel source plus long obtient un meilleur rapport jusqu'à ce que, comme d'autres l'ont dit, il s'approche asymptotiquement de 1,333 ...
Olie
1

C'est une future référence pour moi. Puisque la question porte sur le pire des cas, nous devons prendre en compte les sauts de ligne. Alors que la RFC 1421 définit la longueur de ligne maximale à 64 caractères, la RFC 2045 (MIME) stipule qu'il y aurait 76 caractères au plus sur une ligne.

Ce dernier est ce que la bibliothèque C # a implémenté. Donc, dans un environnement Windows où un saut de ligne est de 2 caractères (\ r \ n), nous obtenons ceci:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

Remarque: Flooring est dû au fait que lors de mon test avec C #, si la dernière ligne se termine à exactement 76 caractères, aucun saut de ligne ne suit.

Je peux le prouver en exécutant le code suivant:

byte[] bytes = new byte[16 * 1024];
Console.WriteLine(Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks).Length);

La réponse pour 16 Ko encodés en base64 avec 76 lignes de caractères: 22422 caractères

Supposons que ce soit le cas sous Linux, Length = Floor(Ceiling(N/3) * 4 * 77 / 76)mais je n'ai pas encore réussi à le tester sur mon noyau .NET.

Lionet Chen
la source