Nach dem Lesen des base64- Wikis ...
Ich versuche herauszufinden, wie die Formel funktioniert:
Bei einer Zeichenfolge mit der Länge von n
ist die base64-Länge
Welches ist : 4*Math.Ceiling(((double)s.Length/3)))
Ich weiß bereits, dass die base64-Länge sein muss %4==0
, damit der Decoder weiß, wie lang der ursprüngliche Text war.
Die maximale Anzahl von Auffüllungen für eine Sequenz kann =
oder sein ==
.
Wiki: Die Anzahl der Ausgabebytes pro Eingabebyte beträgt ungefähr 4/3 (33% Overhead)
Frage:
Wie stimmen die obigen Informationen mit der Ausgabelänge überein ?
4 * n / 3
gibt ungepolsterte Länge.Und runden Sie zum Auffüllen auf das nächste Vielfache von 4 auf, und da 4 eine Potenz von 2 ist, können bitweise logische Operationen verwendet werden.
quelle
$(( ((4 * n / 3) + 3) & ~3 ))
4 * n / 3
schlägt bereits fehln = 1
, ein Byte wird mit zwei Zeichen codiert und das Ergebnis ist eindeutig ein Zeichen.Als Referenz lautet die Längenformel des Base64-Encoders wie folgt:
Wie Sie sagten, erzeugt ein Base64-Encoder, dem
n
Datenbytes gegeben sind, eine Folge von4n/3
Base64-Zeichen. Anders ausgedrückt, alle 3 Datenbytes ergeben 4 Base64-Zeichen. BEARBEITEN : Ein Kommentar weist korrekt darauf hin, dass meine vorherige Grafik das Auffüllen nicht berücksichtigt hat. Die richtige Formel lautetCeiling(4n/3)
.Der Wikipedia-Artikel zeigt genau, wie die ASCII-
Man
ZeichenfolgeTWFu
in ihrem Beispiel in die Base64-Zeichenfolge codiert wurde . Die Eingabezeichenfolge ist 3 Byte oder 24 Bit groß, sodass die Formel korrekt vorhersagt, dass die Ausgabe 4 Byte (oder 32 Bit) lang sein wird :TWFu
. Der Prozess codiert alle 6 Datenbits in eines der 64 Base64-Zeichen. Die 24-Bit-Eingabe geteilt durch 6 ergibt 4 Base64-Zeichen.Sie fragen in einem Kommentar nach der Größe der Codierung
123456
. Unter Berücksichtigung der Tatsache, dass jedes Zeichen dieser Zeichenfolge 1 Byte oder 8 Bit groß ist (unter der Annahme einer ASCII / UTF8-Codierung), codieren wir 6 Byte oder 48 Bit Daten. Nach der Gleichung erwarten wir eine Ausgangslänge von(6 bytes / 3 bytes) * 4 characters = 8 characters
.Durch das Einfügen
123456
in einen Base64-Encoder werdenMTIzNDU2
genau wie erwartet 8 Zeichen erstellt .quelle
floor((3 * (length - padding)) / 4)
. Schauen Sie sich das folgende Wesentliche an .Ganzzahlen
Im Allgemeinen möchten wir keine Doubles verwenden, da wir keine Gleitkommaoperationen, Rundungsfehler usw. verwenden möchten. Sie sind einfach nicht erforderlich.
Aus diesem Grund ist es eine gute Idee, sich daran zu erinnern, wie die Deckenteilung durchgeführt wird:
ceil(x / y)
In Doppel kann geschrieben werden als(x + y - 1) / y
(unter Vermeidung negativer Zahlen, aber Vorsicht vor Überlauf).Lesbar
Wenn Sie sich für die Lesbarkeit entscheiden, können Sie es natürlich auch so programmieren (Beispiel in Java, für C könnten Sie natürlich Makros verwenden):
Inline
Gepolstert
Wir wissen, dass wir jeweils 4 Zeichenblöcke für jeweils 3 Bytes (oder weniger) benötigen. Dann lautet die Formel (für x = n und y = 3):
oder kombiniert:
Ihr Compiler optimiert das
3 - 1
, lassen Sie es also einfach so, um die Lesbarkeit zu gewährleisten.Ungepolstert
Weniger verbreitet ist die ungepolsterte Variante, dafür erinnern wir uns, dass wir jeweils ein Zeichen für jeweils 6 Bits benötigen, aufgerundet:
oder kombiniert:
wir können jedoch immer noch durch zwei teilen (wenn wir wollen):
Unlesbar
Falls Sie Ihrem Compiler nicht vertrauen, dass er die endgültigen Optimierungen für Sie vornimmt (oder wenn Sie Ihre Kollegen verwirren möchten):
Gepolstert
Ungepolstert
Es gibt also zwei logische Berechnungsmethoden, und wir brauchen keine Verzweigungen, Bit-Ops oder Modulo-Ops - es sei denn, wir wollen es wirklich.
Anmerkungen:
quelle
Ich denke, die gegebenen Antworten verfehlen den Punkt der ursprünglichen Frage, nämlich wie viel Speicherplatz zugewiesen werden muss, um zur base64-Codierung für eine gegebene binäre Zeichenfolge mit einer Länge von n Bytes zu passen.
Die Antwort ist
(floor(n / 3) + 1) * 4 + 1
Dies umfasst das Auffüllen und ein abschließendes Nullzeichen. Möglicherweise benötigen Sie den Floor-Aufruf nicht, wenn Sie Ganzzahlarithmetik ausführen.
Inklusive Auffüllen benötigt eine base64-Zeichenfolge vier Bytes für jeden Drei-Byte-Block der ursprünglichen Zeichenfolge, einschließlich aller Teilblöcke. Ein oder zwei zusätzliche Bytes am Ende der Zeichenfolge werden weiterhin in vier Bytes in der Base64-Zeichenfolge konvertiert, wenn Padding hinzugefügt wird. Sofern Sie keine ganz bestimmte Verwendung haben, ist es am besten, die Polsterung hinzuzufügen, normalerweise ein Gleichheitszeichen. Ich habe ein zusätzliches Byte für ein Nullzeichen in C hinzugefügt, da ASCII-Zeichenfolgen ohne dieses Zeichen etwas gefährlich sind und Sie die Zeichenfolgenlänge separat tragen müssen.
quelle
Hier ist eine Funktion zum Berechnen der Originalgröße einer codierten Base 64-Datei als Zeichenfolge in KB:
quelle
Während alle anderen über algebraische Formeln diskutieren, verwende ich lieber BASE64 selbst, um mir zu sagen:
525
710
Die Formel von 3 Bytes, die durch 4 base64-Zeichen dargestellt werden, scheint also korrekt zu sein.
quelle
Mir scheint, dass die richtige Formel sein sollte:
quelle
(In einem Versuch, eine prägnante und dennoch vollständige Ableitung zu geben.)
Jedes Eingangsbyte hat 8 Bits, also erhalten wir für n Eingangsbytes:
Alle 6 Bits ist ein Ausgangsbyte, also:
Dies ist ohne Polsterung.
Mit dem Auffüllen runden wir das auf ein Vielfaches von vier Ausgabebytes auf:
Die erste Äquivalenz finden Sie unter Verschachtelte Abteilungen (Wikipedia).
Unter Verwendung ganzzahliger Arithmetik kann Ceil ( n / m ) als ( n + m - 1) div m berechnet werden , daher erhalten wir:
Zur Veranschaulichung:
Schließlich werden im Fall der MIME Base64-Codierung zwei zusätzliche Bytes (CR LF) pro 76 Ausgangsbytes benötigt, die auf- oder abgerundet werden, je nachdem, ob eine abschließende neue Zeile erforderlich ist.
quelle
Ich glaube, dass dies eine genaue Antwort ist, wenn n% 3 nicht Null ist, nein?
Mathematica-Version:
Habe Spaß
GI
quelle
Einfache Implementierung in Javascript
quelle
Schauen Sie sich für alle Personen, die C sprechen, diese beiden Makros an:
Von hier genommen .
quelle
In Windows - ich wollte die Größe des Puffers mit der Größe mime64 schätzen, aber alle genauen Berechnungsformeln haben bei mir nicht funktioniert - habe ich schließlich eine ungefähre Formel wie diese erhalten:
Mine64-String-Zuordnungsgröße (ungefähr) = (((4 * ((binäre Puffergröße) + 1)) / 3) + 1)
Das letzte +1 - es wird für ASCII-Null verwendet - das letzte Zeichen muss zugewiesen werden, um die Null-Endung zu speichern - aber warum ist die "Binärpuffergröße" + 1 - ich vermute, dass es ein mime64-Abschlusszeichen gibt? Oder dies ist möglicherweise ein Ausrichtungsproblem.
quelle
Wenn jemand daran interessiert ist, die @ Pedro Silva-Lösung in JS zu erreichen, habe ich dieselbe Lösung dafür portiert:
quelle
Ich sehe die vereinfachte Formel nicht in anderen Antworten. Die Logik wird behandelt, aber ich wollte eine grundlegendste Form für meine eingebettete Verwendung:
HINWEIS: Bei der Berechnung der ungepolsterten Anzahl wird die ganzzahlige Division aufgerundet, dh Divisor-1 hinzugefügt, in diesem Fall +2
quelle