Entwicklertools · Base64-Encoder und -Decoder
Base64 in UTF-8 ohne Mojibake dekodieren: atob plus TextDecoder
· Wie es funktioniert
base64 Kodierung Unicode
atob() gibt als Zeichen getarnte Bytes zurück, weshalb akzentuierter Text nach der Dekodierung fehlerhaft aussieht. Dieser Beitrag zeigt die richtige Pipeline von Base64 zu Bytes zu UTF-8-Text und wie man das Fehlermuster erkennt.
Die API-Antwort, die in „Café“ dekodiert wird – ein konkretes Mojibake-Symptom und die zwei Bytes hinter den beiden falschen Zeichen
Eine Base64-Zeichenfolge Q2Fmw6k= dekodiert in Bytes (67, 97, 102, 195, 169), die UTF-8 Textcafé sind. In den naiven Decoder einfügen (nur ATOB- und String-Konvertierung) und die Ausgabe ist oft Café, wobei jeder Akzent durch zwei falsche Zeichen ersetzt wird. Dieser Mojibake geschieht, weil atob eine Bytefolge (Codeeinheiten 0–255) und keinen UTF-8-Text zurückgibt. Die Bytes 195 und 169 kodieren das akzentuierte é in UTF-8.
Wenn man sie so behandelt, als wären es separate lateinische 1 Zeichen, ergibt sich ein Mojibake-Muster. Die richtige Pipeline ist atob (Bytes als Zeichenfolge), dann TextDecoder (Bytes als UTF-8 interpretieren) und der Originaltext kommt zurück. Die atob-Funktion ist nicht kaputt; Es ist für Binärdaten konzipiert. Sein Name kommt von ASCII-to-binary und die von ihm erzeugte Binärzeichenfolge ist eine Folge von Codeeinheiten 0–255, die jeweils ein Byte darstellen.
Was atob() tatsächlich zurückgibt – eine Zeichenfolge von Codeeinheiten 0–255, die für Bytes stehen, nicht für dekodierten Text
Wenn Sie es mit Q2Fmw6k= (Standard Base64) füttern, wird eine Zeichenfolge ausgegeben, bei der jedes Zeichen ein Byte ist: Codeeinheit 67, dann 97, dann 102, dann 195, dann 169. Wenn Sie diese Zeichenfolge direkt anzeigen oder als Latin-1-Text interpretieren, sehen Sie eine verstümmelte Ausgabe. Der fehlende Schritt besteht darin, Codeeinheiten in ein Byte-Array umzuwandeln und das Array dann als UTF-8 zu dekodieren.
Die charCodeAt-Schleife stellt Bytewerte wieder her: Rufen Sie für jedes Zeichen in der atob-Ausgabe charCodeAt auf, um die Codeeinheit (Nummer 0–255) abzurufen und in Uint8Array zu speichern. Sobald ein Byte-Array vorhanden ist, übergeben Sie es mit dem Zeichensatz utf-8 an TextDecoder. TextDecoder liest die Bytesequenz und interpretiert sie als UTF-8-Text, indem er Bytesequenzen wie (195, 169) zu einzelnen Zeichen wie é kombiniert. Bytes (67, 97, 102, 195, 169) werden zu einer vierstelligen Zeichenfolge Café. Die Schleife ist bewusst langweilig: Lesen Sie jede zurückgegebene Codeeinheit mit charCodeAt und weisen Sie sie der passenden Uint8Array-Position zu. Dort findet keine Zeichensatzentscheidung statt. Die einzige Interpretation erfolgt, wenn TextDecoder dieses Array empfängt und UTF-8 mit schwerwiegender Fehlerbehandlung anwendet.
Diese Zeichenfolge in ein Uint8Array umwandeln – die charCodeAt-Schleife und warum es sich um eine Bytekopie und nicht um eine Konvertierung handelt
Dieser zweistufige Prozess – Byte-Wiederherstellung, dann UTF-8-Interpretation – ist das, was der Base64-Encoder und -Decoder intern ausführt. Das Mojibake-Muster ist ein verräterisches Zeichen für diesen Fehler. Wenn „Café“ als „Café“ angezeigt wird, sehen Sie eine lateinische 1-Interpretation von UTF-8 Bytes. UTF-8 Bytes für é sind 0xC3 0xA9 (dezimal 195, 169). Im lateinischen 1 ist die Codeeinheit 195 Ã und die Codeeinheit 169 ist ©.
Wenn die Bytesequenz UTF-8 so gelesen wird, als ob jedes Byte ein separates lateinisches 1-Zeichen wäre, erzeugt jede Multibyte-Sequenz UTF-8 falsche Ersatzzeichen. Wenn Café als Caf erscheint, gefolgt von einem Ersatzzeichen, oder als Caf? oder Caf plus U+FFFD, Sie sehen einen anderen Fehler: Der Decoder hat die Bytesequenz nicht als gültig erkannt UTF-8. Ein konkretes Beispiel: Base64 SGVsbG8sIOS4lueVjCEg8J-Zgg== dekodiert wie folgt.
TextDecoder und die Zeichensatzentscheidung – Dekodierung als UTF-8 und warum der Zeichensatz eine separate Tatsache ist, müssen Sie wissen
atob erzeugt eine Binärzeichenfolge mit Bytes (72, 101, 108, 108, 111, 44, 32, 228, 184, 180, 149, 140, 33, 32, 240, 159, 152, 130). Die ersten sechs Bytes sind ASCII: werden Hallo. Die Bytes 228, 184, 180 sind drei Byte lange UTF-8-Sequenzen, die CJK-Zeichen darstellen. Die Bytes 149, 140 sind Teil der nächsten Sequenz. Die vollständige Sequenz enthält eine Vier-Byte-Emoji-Sequenz (240, 159, 152, 130) für das letzte Zeichen.
Bei korrekter Verarbeitung durch TextDecoder ergeben alle Bytes zusammen den Originaltext mit gemischtem Skript. UTF-8 Bytesequenzen haben vorhersagbare Längen: Byte, das mit 0xxxxxxx beginnt, ist Einzelbyte-ASCII; Byte, das mit 110xxxxxx beginnt, erwartet das folgende Byte, das mit 10xxxxxx beginnt (insgesamt zwei Bytes); Byte, das mit 1110xxxx beginnt, erwartet zwei folgende Bytes (insgesamt drei Bytes); Byte, das mit 11110xxx beginnt, erwartet drei folgende Bytes (insgesamt vier Bytes). Für ein gemischtes CJK- und Emoji-Beispiel ist die Byte-Ansicht besonders diagnostisch, da die ASCII-Intuition nicht mehr hilft. Zu jedem sichtbaren Symbol gehören mehrere Bytes, und eine Löschung um ein Byte verschiebt die verbleibende Sequenz in den ungültigen UTF-8. Eine strikte Dekodierung verwandelt diese Verschiebung in einen benannten Fehler statt in einen plausibel aussehenden Schaden.
Arbeitsbeispiel: Dekodieren einer Base64-Zeichenfolge, die CJK und ein Emoji enthält – Bytes, Codepunkte und die endgültige Zeichenfolge im Vergleich zum Original
Die mit 1111110x beginnende Sequenz ist in UTF-8 ungültig (für die Zukunft reserviert, nicht verwendet). Byte, das mit 10xxxxxx beginnt, sollte niemals als Lead-Byte erscheinen; es ist eine Fortsetzung. Wenn der Bytestream gegen Regeln verstößt, ist er ungültig UTF-8. TextDecoder mit dem Zeichensatz utf-8 interpretiert Arrays nach diesen Regeln und ist für gültige Sequenzen erfolgreich. Bei ungültig wird ein Fehler gemeldet.
Base64-Encoder und -Decoder verwendet TextDecoder mit dem Strict-Mode-Flag „true“. Dies bedeutet, dass ungültiges UTF-8 einen Fehler auslöst, anstatt stillschweigend Ersatzzeichen (U+FFFD) einzufügen. Wenn die Base64-Zeichenfolge in Bytes dekodiert wird, die nicht gültig sind UTF-8, löst der strikte Modus aus, anstatt mit verstümmeltem Text fortzufahren. Dies ist eine Designentscheidung: Binäre Nutzlasten (Bilder, Schlüssel, komprimierte Daten) sind kein Text und sollten nicht als Text dekodiert werden.
Erkennen des Musters: Ã, †und � – wie man ein Base64-Problem von einem Zeichensatzproblem unterscheidet
Wenn versucht wird, JPEG als Base64 zu dekodieren, stellt der Bytestrom kein gültiges UTF-8 dar und eine strikte Dekodierung wird ihn ablehnen. Das Tool bietet eine Hex-Ansicht für solche Nutzlasten: Sie können rohe Bytes sehen, ohne so zu tun, als wären sie Text. Um UTF-8-Dekodierungsfehler zu erkennen, müssen Bytes im Kontext betrachtet werden. Sind es ungerade Zahlen, wo eine Mehrbyte-Sequenz erwartet wird?
Ist das erste Byte der möglichen Sequenz ungültig (beginnend mit 10xxxxxx)? Fehlen Fortsetzungsbytes? Die Byte-Ausgabe-Schaltfläche bietet den saubersten Zweig in der Untersuchung. Wenn Hex angezeigt wird, die Textdecodierung jedoch fehlschlägt, war die Base64-Analyse erfolgreich und die Nutzlast ist entweder binär, beschädigt oder mit einem anderen Zeichensatz codiert. Durch das Ändern der Base64-Interpunktion kann eine Zeichensatzinkongruenz nicht behoben werden, nachdem bereits die richtigen Bytes aufgetreten sind.
Was dies nicht abdeckt – UTF-16-Nutzdaten, Binärausgabe wie Bilder und Behandlung ungültiger Bytes
Muster sind konsistent. Ein einzelnes Byte 0xFF ist in UTF-8 niemals gültig; Es darf kein ASCII-Byte sein (nur 0–127 sind ASCII) und kein Lead-Byte (Lead-Bytes sind 0xC0–0xFD, 0xFF ist reserviert). Einzelne Ersatzzeichen (UTF-16-Konzept) können nicht in UTF-8 erscheinen; Wenn Sie die Bytesequenz 0xED 0xA0 0x80 sehen (die den Ersatz U+D800 im UTF-8-Stil codiert), ist sie ungültig UTF-8.
Eine historische Problemumgehung ist btoa(unescape(encodeURIComponent(text))). encodeURIComponent wandelt Café in %C3%A9 um (Prozentkodierung von UTF-8 Bytes), unescape packt es als Codeeinheiten neu, btoa kodiert Codeeinheiten. Dies funktioniert für die meisten Texte, ist jedoch bei einzelnen Ersatzzeichen fragil und schwer zu lesen. Moderne Pipelines – TextEncoder in Bytes, dann Base64 – sind klarer und standardisiert. TextEncoder ist in alle modernen Browser und Node.js integriert und trifft so die richtige Wahl. UTF-16, ältere Einzelbyte-Codierungen und beliebige Dateiinhalte erfordern einen für diese Bytes ausgewählten Decoder oder einen binärfähigen Viewer. ToolAcre rät absichtlich nicht dazu. Durch Raten könnte eine ungültige Sequenz in irreführenden Text umgewandelt werden, während ein Hex-Dump jedes Byte für eine spätere, fundierte Interpretation bewahrt.
Takeaway: Base64 liefert Ihnen Bytes, UTF-8 liefert Ihnen Text – wie der Base64-Encoder und -Decoder beide Schritte ausführt, damit der dekodierte Text genau mit der Eingabe übereinstimmt
Wenn Sie eine Base64-Zeichenfolge haben und UTF-8-Text benötigen, sind die vollständigen Schritte: Base64 in Bytes dekodieren (mithilfe von atob oder einer Base64-Dekodierungsbibliothek), Uint8Array aus Bytes erstellen, Array mit dem Zeichensatz utf-8 an TextDecoder übergeben, Ergebnis als Zeichenfolge lesen.
Wenn es sich bei der Eingabe um Binärdaten und nicht um Text handelt, überspringen Sie TextDecoder und untersuchen Sie die Bytes direkt. Der Base64-Encoder und -Decoder bietet eine hexadezimale Byteansicht und behält Werte bei, die bei einer strikten UTF-8-Dekodierung abgelehnt würden. Dieser Fork ist diagnostisch: Erfolgreiche Bytes plus fehlgeschlagener Text bedeuten, dass die Base64-Analyse funktioniert hat, während die Nutzlast binär, beschädigt oder mit einem Zeichensatz codiert ist, den dieses Tool nicht errät.