Wanneer Base64 het Chinees lijkt te breken, is het probleem meestal de grens tussen tekens en bytes. Base64 weet niet dat een reeks Chinese tekst of emoji vertegenwoordigt. Het behoudt bytes; de applicatie kiest hoe die bytes worden geproduceerd en geïnterpreteerd.
Volg de bytes
Het karakter 中 is U+4E2D. In UTF-8 gebruikt het de bytes E4 B8 AD, waarvan de Base64 representatie is 5Lit. Een andere tekencodering levert andere bytes op en dus een andere Base64-waarde. Maak aan beide kanten afspraken over UTF-8 voordat u de gecodeerde tekenreeksen vergelijkt.
const bytes = new TextEncoder().encode('中');
console.log([...bytes]); // [228, 184, 173]
console.log([...bytes].map(b => b.toString(16)).join(' ')); // e4 b8 ad
Emoji illustreren nog een ander onderscheid: JavaScript '😊'.length bestaat uit twee UTF-16 code-eenheden, terwijl de UTF-8-weergave vier bytes heeft. Geen van beide getallen op zichzelf is een telling van zichtbare, door de gebruiker waargenomen tekens in willekeurige tekst. Gebruik bytelengte voor bestands- en transportberekeningen.
Maak vervanging zichtbaar
Het vervangende teken � kan betekenen dat een eerdere decoder al informatie verloren heeft. Zodra onbekende bytes in een string zijn vervangen en die string opnieuw is gecodeerd, kunnen de oorspronkelijke waarden doorgaans niet meer worden gereconstrueerd. Inspecteer de onbewerkte gedecodeerde byte-array voordat u verdere conversies uitvoert.
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.'); }
Normalisatie is een aparte operatie
Twee tekenreeksen kunnen er identiek uitzien terwijl ze verschillende Unicode-reeksen bevatten. De letter é met accent kan een vooraf samengesteld teken zijn of een e gevolgd door een combinatieaccent. UTF-8 en Base64 behouden dat verschil correct. Als uw toepassing genormaliseerde tekst wil, kies dan expliciet een normalisatieformulier en pas dit toe vóór het coderen; noem een gewijzigd resultaat nooit een byte-behoudende reparatie.
Controleer ook onzichtbare tekens, regeleinden en een eventuele bytevolgordemarkering als de resultaten verschillen. Dit zijn echte invoerbytes, niet noodzakelijkerwijs encoderbugs. Bij ondertekende berichten en controlesommen verandert zelfs een onzichtbaar verschil het resultaat.
Een betrouwbare volgorde voor het oplossen van problemen is: bewaar de bron, inspecteer bytes, identificeer de verwachte tekencodering, decodeer met expliciete foutafhandeling en overweeg pas daarna normalisatie. MDN: btoa() legt uit waarom directe browser-btoa-aanroepen ongeschikt zijn voor willekeurige Unicode-tekst. Binaire bestanden moeten de tekstdecodering volledig omzeilen.