Base64 og UTF-8: diagnosticer kinesisk tekst, emoji og erstatningstegn

Spor tekst gennem Unicode og UTF-8 bytes, skeln afkodningsfejl fra normalisering, og bevar ugyldig binær input.

Når Base64 ser ud til at "bryder kinesisk", er problemet normalt grænsen mellem tegn og bytes. Base64 ved ikke, at en sekvens repræsenterer kinesisk tekst eller emoji. Det bevarer bytes; applikationen vælger, hvordan disse bytes produceres og fortolkes.

Følg bytes

Tegnet 中 er U+4E2D. I UTF-8 bruger den bytes E4 B8 AD, hvis Base64 repræsentation er 5Lit. En anden tegnkodning producerer forskellige bytes og derfor en anden Base64 værdi. Enig om UTF-8 i begge ender, før du sammenligner kodede strenge.

const bytes = new TextEncoder().encode('中');
console.log([...bytes]); // [228, 184, 173]
console.log([...bytes].map(b => b.toString(16)).join(' ')); // e4 b8 ad

Emoji illustrerer en anden sondring: JavaScript '😊'.length er to UTF-16 kodeenheder, mens dens UTF-8 repræsentation har fire bytes. Ingen af ​​tallene alene er en optælling af synlige brugeropfattede tegn i vilkårlig tekst. Brug byte-længde til fil- og transportberegninger.

Gør udskiftningen synlig

Erstatningstegnet � kan betyde, at en tidligere dekoder allerede har mistet information. Når ukendte bytes først er blevet erstattet i en streng, og den streng er omkodet, kan de oprindelige værdier generelt ikke rekonstrueres. Undersøg det rå-dekodede byte-array, før du foretager yderligere konverteringer.

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 er en separat operation

To strenge kan se identiske ud, mens de indeholder forskellige Unicode-sekvenser. Det accentuerede bogstav é kan være et prækomponeret tegn eller et e efterfulgt af en kombinerende accent. UTF-8 og Base64 bevarer den forskel korrekt. Hvis din applikation ønsker normaliseret tekst, skal du vælge en normaliseringsform eksplicit og anvende den før kodning; kald aldrig et ændret resultat for en byte-bevarende reparation.

Tjek også usynlige tegn, linjeafslutninger og et muligt byte-rækkefølgemærke, når resultaterne er forskellige. Disse er rigtige input-bytes, ikke nødvendigvis encoder-fejl. For signerede beskeder og kontrolsummer ændrer selv en usynlig forskel resultatet.

En pålidelig fejlfindingsrækkefølge er: bevar kilden, inspicér bytes, identificer den forventede tegnkodning, afkod med eksplicit fejlhåndtering, og overvej først derefter normalisering. MDN: btoa() forklarer, hvorfor direkte browser btoa-kald er uegnede til vilkårlig Unicode-tekst. Binære filer bør omgå tekstafkodning helt.