När Base64 verkar "bryta kinesiska" är problemet vanligtvis gränsen mellan tecken och byte. Base64 vet inte att en sekvens representerar kinesisk text eller emoji. Det bevarar bytes; applikationen väljer hur dessa bytes produceras och tolkas.
Följ byten
Tecknet 中 är U+4E2D. I UTF-8 använder den byte E4 B8 AD, vars Base64 representation är 5Lit. En annan teckenkodning ger olika byte och därför ett annat Base64 värde. Kom överens om UTF-8 i båda ändarna innan du jämför kodade strängar.
const bytes = new TextEncoder().encode('中');
console.log([...bytes]); // [228, 184, 173]
console.log([...bytes].map(b => b.toString(16)).join(' ')); // e4 b8 ad
Emoji illustrerar en annan distinktion: JavaScript '😊'.length är två UTF-16-kodenheter, medan dess UTF-8-representation har fyra byte. Ingendera siffran ensam är en räkning av synliga användaruppfattade tecken i godtycklig text. Använd bytelängd för fil- och transportberäkningar.
Gör ersättningen synlig
Ersättningstecknet � kan betyda att en tidigare avkodare redan har förlorat information. När väl okända bytes har ersatts i en sträng och den strängen kodats om, kan de ursprungliga värdena i allmänhet inte rekonstrueras. Inspektera den råavkodade bytematrisen innan du gör ytterligare omvandlingar.
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.'); }
Normalisering är en separat operation
Två strängar kan se identiska ut samtidigt som de innehåller olika Unicode-sekvenser. Den accentuerade bokstaven é kan vara ett förkomponerat tecken eller ett e följt av en kombinerande accent. UTF-8 och Base64 behåller den skillnaden korrekt. Om din applikation vill ha normaliserad text, välj en normaliseringsform explicit och använd den innan du kodar; kalla aldrig ett ändrat resultat för en bytebevarande reparation.
Kontrollera även osynliga tecken, radslut och en möjlig byte-ordningsmarkering när resultaten skiljer sig. Dessa är riktiga indatabytes, inte nödvändigtvis kodarbuggar. För signerade meddelanden och kontrollsummor ändrar även en osynlig skillnad resultatet.
En tillförlitlig felsökningsordning är: bevara källan, inspektera bytes, identifiera den förväntade teckenkodningen, avkoda med explicit felhantering och överväg bara normalisering. MDN: btoa() förklarar varför direkta btoa-anrop i webbläsaren är olämpliga för godtycklig Unicode-text. Binära filer bör kringgå textavkodning helt.