Wenn Base64 „Chinesisch zu brechen“ scheint, liegt das Problem normalerweise an der Grenze zwischen Zeichen und Bytes. Base64 weiß nicht, dass eine Sequenz chinesischen Text oder Emoji darstellt. Es bewahrt Bytes; Die Anwendung entscheidet, wie diese Bytes erzeugt und interpretiert werden.
Folgen Sie den Bytes
Das Zeichen 中 ist U+4E2D. In UTF-8 werden die Bytes E4 B8 AD verwendet, deren Darstellung Base64 ist 5Lit. Eine andere Zeichenkodierung erzeugt unterschiedliche Bytes und daher einen anderen Base64-Wert. Vereinbaren Sie an beiden Enden UTF-8, bevor Sie codierte Zeichenfolgen vergleichen.
const bytes = new TextEncoder().encode('中');
console.log([...bytes]); // [228, 184, 173]
console.log([...bytes].map(b => b.toString(16)).join(' ')); // e4 b8 ad
Emoji veranschaulichen eine weitere Unterscheidung: JavaScript '😊'.length besteht aus zwei UTF-16-Codeeinheiten, während seine UTF-8-Darstellung vier Bytes hat. Keine der beiden Zahlen allein ist eine Zählung der sichtbaren, vom Benutzer wahrgenommenen Zeichen in beliebigem Text. Verwenden Sie die Bytelänge für Datei- und Transportberechnungen.
Ersatz sichtbar machen
Das Ersatzzeichen � kann bedeuten, dass ein früherer Decoder bereits Informationen verloren hat. Sobald unbekannte Bytes in einer Zeichenfolge ersetzt wurden und diese Zeichenfolge neu codiert wurde, können die ursprünglichen Werte im Allgemeinen nicht wiederhergestellt werden. Überprüfen Sie das rohe dekodierte Byte-Array, bevor Sie weitere Konvertierungen vornehmen.
const decoder = new TextDecoder('utf-8', { fatal: true });
console.log(decoder.decode(Uint8Array.of(0xe4, 0xb8, 0xad))); // 中
try { decoder.decode(Uint8Array.of(0xff)); }
catch { console.log('Invalid UTF-8; preserve the original byte.'); }
Die Normalisierung ist ein separater Vorgang
Zwei Zeichenfolgen können identisch aussehen, obwohl sie unterschiedliche Unicode-Sequenzen enthalten. Der akzentuierte Buchstabe é kann ein vorkomponiertes Zeichen oder ein e gefolgt von einem kombinierenden Akzent sein. UTF-8 und Base64 bewahren diesen Unterschied korrekt. Wenn Ihre Anwendung normalisierten Text wünscht, wählen Sie explizit eine Normalisierungsform aus und wenden Sie diese vor der Codierung an. Nennen Sie ein geändertes Ergebnis niemals eine byteerhaltende Reparatur.
Überprüfen Sie auch unsichtbare Zeichen, Zeilenenden und eine mögliche Markierung der Bytereihenfolge, wenn die Ergebnisse unterschiedlich sind. Dabei handelt es sich um echte Eingabebytes, nicht unbedingt um Encoderfehler. Bei signierten Nachrichten und Prüfsummen verändert bereits ein unsichtbarer Unterschied das Ergebnis.
Eine zuverlässige Reihenfolge zur Fehlerbehebung lautet: Bewahren Sie die Quelle auf, überprüfen Sie die Bytes, identifizieren Sie die erwartete Zeichenkodierung, dekodieren Sie mit expliziter Fehlerbehandlung und ziehen Sie erst dann eine Normalisierung in Betracht. MDN: btoa() erklärt, warum direkte Browser-BTOA-Aufrufe für beliebigen Unicode-Text ungeeignet sind. Binärdateien sollten die Textdekodierung vollständig umgehen.