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

Spor tekst gjennom Unicode og UTF-8 byte, skille dekodingsfeil fra normalisering, og bevar ugyldig binærinndata.

Når Base64 ser ut til å "bryte kinesisk", er problemet vanligvis grensen mellom tegn og byte. Base64 vet ikke at en sekvens representerer kinesisk tekst eller emoji. Den bevarer bytes; applikasjonen velger hvordan disse bytene produseres og tolkes.

Følg bytene

Tegnet 中 er U+4E2D. I UTF-8 bruker den byte E4 B8 AD, hvis Base64 representasjon er 5Lit. En annen tegnkoding produserer forskjellige byte og derfor en annen Base64 verdi. Bli enige om UTF-8 i begge ender før du sammenligner kodede strenger.

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 annen forskjell: JavaScript '😊'.length er to UTF-16 kodeenheter, mens UTF-8 representasjonen har fire byte. Ingen av tallene alene er en telling av synlige brukeroppfattede tegn i vilkårlig tekst. Bruk bytelengde for fil- og transportberegninger.

Gjør erstatningen synlig

Erstatningstegnet � kan bety at en tidligere dekoder allerede har mistet informasjon. Når ukjente byte har blitt erstattet i en streng og den strengen er kodet på nytt, kan de opprinnelige verdiene vanligvis ikke rekonstrueres. Inspiser den rå dekodede byte-matrisen før du foretar ytterligere 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 egen operasjon

To strenger kan se identiske ut mens de inneholder forskjellige Unicode-sekvenser. Den aksenterte bokstaven é kan være ett forhåndskomponert tegn eller en e etterfulgt av en kombinerende aksent. UTF-8 og Base64 bevarer den forskjellen på riktig måte. Hvis applikasjonen din ønsker normalisert tekst, velg et normaliseringsskjema eksplisitt og bruk det før koding; kall aldri et endret resultat for en bytebevarende reparasjon.

Sjekk også usynlige tegn, linjeavslutninger og et mulig byte-rekkefølgemerke når resultatene er forskjellige. Dette er ekte inngangsbyte, ikke nødvendigvis kodefeil. For signerte meldinger og kontrollsummer endrer selv en usynlig forskjell resultatet.

En pålitelig feilsøkingsrekkefølge er: bevar kilden, inspiser byte, identifiser den forventede tegnkodingen, dekode med eksplisitt feilhåndtering, og først da vurder normalisering. MDN: btoa() forklarer hvorfor direkte nettleser btoa-anrop er uegnet for vilkårlig Unicode-tekst. Binære filer bør omgå tekstdekoding helt.