Base64: Was ist die schlimmste mögliche Zunahme der Speicherplatznutzung?

166

Wenn ein Server eine base64-Zeichenfolge empfangen hat und vor der Konvertierung die Länge überprüfen wollte, sagen wir, er wollte immer zulassen, dass das endgültige Byte-Array 16 KB groß ist. Wie groß könnte ein 16-KB-Byte-Array möglicherweise werden, wenn es in eine Base64-Zeichenfolge konvertiert wird (unter der Annahme eines Bytes pro Zeichen)?

Bryan Field
quelle

Antworten:

242

Base64 codiert jeden Satz von drei Bytes in vier Bytes. Außerdem wird die Ausgabe so aufgefüllt, dass sie immer ein Vielfaches von vier ist.

Dies bedeutet, dass die Größe der Basis-64-Darstellung einer Zeichenfolge der Größe n wie folgt ist:

ceil(n / 3) * 4

Für ein 16-kB-Array ist die Basis-64-Darstellung also Ceil (16 * 1024/3) * 4 = 21848 Byte lang ~ = 21,8 kB.

Eine grobe Annäherung wäre, dass die Größe der Daten auf 4/3 des Originals erhöht wird.

R. Martinho Fernandes
quelle
Müssen wir der Länge 2 hinzufügen oder nicht?
VIceBerg
@vIceBerg, Es hängt davon ab, ob Sie ceilmit floatZahlen oder nur intZahlen verwenden. (und nein ceil)
Bryan Field
7
Ich denke, der einfachere Weg, dies auszudrücken, besteht darin, dass Sie 1/3 der Originalgröße hinzufügen.
MVMN
1
In dem von Ihnen vorgeschlagenen Beispiel würde die Anzeige des Ergebnisses in derselben Messreihenfolge die Qualität der Antwort etwas erhöhen (21,3 KB anstelle von 21848 Byte).
Ivan De Paz Centeno
36

Aus Wikipedia

Beachten Sie, dass bei einer Eingabe von n Bytes die Ausgabe (n + 2 - ((n + 2)% 3)) / 3 * 4 Bytes lang ist, so dass die Anzahl der Ausgabebytes pro Eingabebyte gegen 4/3 konvergiert oder 1,33333 für große n.

16 kb * 4/3 ergeben also sehr wenig mehr als 21,3 'kb oder 21848 Bytes, um genau zu sein.

Hoffe das hilft

Binärer Sorgen
quelle
11

16 KB sind 131.072 Bit. Base64 packt 24-Bit-Puffer in vier 6-Bit-Zeichen pro Stück, sodass Sie 5.462 * 4 = 21.848 Bytes haben.

Chris Heald
quelle
5

Da es sich um die schlechteste Erhöhung handelte, muss ich hinzufügen, dass es normalerweise Zeilenumbrüche bei jeweils 80 Zeichen gibt. Dies bedeutet, dass beim Speichern von Base64-codierten Daten in einer Textdatei unter Windows 2 Bytes hinzugefügt werden, unter Linux 1 Byte für jede Zeile.

Die Zunahme gegenüber der tatsächlichen Codierung wurde oben beschrieben.

Zsolt Sky
quelle
3
Ist das nicht der Extremfall, dass 1 Quellbyte zu 4 Base64-Bytes wird, also eine 4-fache Erhöhung? Jedes längere Quellmaterial erhält ein besseres Verhältnis, bis es sich, wie andere gesagt haben, asymptotisch 1,333 nähert ...
Olie
1

Dies ist eine zukünftige Referenz für mich. Da die Frage im schlimmsten Fall ist, sollten wir Zeilenumbrüche berücksichtigen. Während RFC 1421 die maximale Zeilenlänge auf 64 Zeichen definiert, gibt RFC 2045 (MIME) an, dass sich höchstens 76 Zeichen in einer Zeile befinden.

Letzteres hat die C # -Bibliothek implementiert. In einer Windows-Umgebung, in der ein Zeilenumbruch 2 Zeichen (\ r \ n) beträgt, erhalten wir Folgendes:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

Hinweis: Der Bodenbelag liegt daran, dass während meines Tests mit C #, wenn die letzte Zeile mit genau 76 Zeichen endet, kein Zeilenumbruch folgt.

Ich kann es beweisen, indem ich den folgenden Code ausführe:

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

Die Antwort für 16 kByte, die mit 76 Zeichenzeilen an base64 codiert wurden: 22422 Zeichen

Angenommen, unter Linux wäre dies der Fall, Length = Floor(Ceiling(N/3) * 4 * 77 / 76)aber ich bin noch nicht dazu gekommen, es auf meinem .NET-Kern zu testen.

Lionet Chen
quelle