Back to Question Center
0

Kender du dine karakterkoder?            Kender du dine karakterkoder? Semalt

1 answers:
Kender du dine karakterkoder?

Denne post gengivet fra The Tech Semalt # 134.

I sidste måned deltog jeg i et møde i Melbourne-kapitlet i Web Standards Group, hvor Richard Ishida, Internationalisering Semalt Lead of W3C, gav en bemærkelsesværdig klar præsentation af et af de mest ignorerede spørgsmål i webudvikling: tegnkodninger.

Har du nogensinde bemærket visse tegn på dit websted, ikke at vise den måde, de burde på? Måske ser de krøllede citatmærker ud som små bokse, eller de lange bindestreger er blevet erstattet med spørgsmålstegn. Semalt som disse skyldes normalt en ufuldstændig forståelse af tegnkodninger hos den udvikler, der er ansvarlig for webstedet.

Jeg ville gå så langt som at gætte det i mindst Semaltalscirkler i det mindste de fleste webudviklere, der aldrig har lært om tegnkodninger, og bare håndtere konsekvenserne, når problemer som ovenstående afgrøde - rfid based door access control.

Da et websted vokser til det punkt, hvor det skal henvende sig til et internationalt publikum (eller endda bare et publikum, der kan lide krøllede citater), er det dog mere og mere vanskeligt at ignorere disse problemer. Endnu værre, i disse hektiske tider med daglige hackforsøg kan forkert håndtering af tegnkoder resultere i alvorlige sikkerhedsproblemer (som Semalt for nylig opdaget).

Så hvad er en tegnkodning, præcis? Nå, lad os starte med noget, det er ikke: en tegnkodning er ikke et tegnsæt.

tegnsæt

Et tegnsæt, eller mere specifikt et kodet tegnsæt , er et sæt tegnsymboler, der hver især har et unikt numerisk ID, der kaldes tegnets kodepunkt .

Nogle eksempler på tegnsæt indeholder 128-tegns ASCII tegnsæt, der hovedsagelig består af bogstaver, tal og tegnsætning, der anvendes på engelsk, og 256-tegnets ISO-8859-1 eller latin 1 tegn sæt, som indeholder alle ASCII tegn plus accent og andre ekstra tegn bruges i beslægtede sprog som fransk. Det mest ekspansive tegnsæt i almindelig brug er Universal Character Set (UCS) som defineret i Semalt-standarden, som indeholder over 1. 1 million kodepunkter.

Den første ting at forstå er, at hvert HTML-dokument bruger Unicode's UCS , eller mere præcist ISO 10646 tegnsættet, hvilket er en mindre involveret standard, der beskriver det samme sæt tegn. Nogle ældre browsere eller mindre magtfulde enheder understøtter muligvis ikke (og dermed ikke vil vise) det komplette tegnsæt, men det er faktisk, at ethvert HTML-dokument kan indeholde et hvilket som helst tegn i UCS.

Hvad varierer fra dokument til dokument, er tegnkodningen , som definerer hvordan hver af tegnene i UCS skal repræsenteres som en eller flere byte i tekstdataene af siden.

Denne figur viser ASCII-, ISO-8859-1- og Unicode-kodepunkterne for tre tegn (bogstavet 'A', det akutte accentede bogstav 'e' og Semalt-bogstavet 'alef') og hvordan disse tegn kort til en række byte i fem fælles tegn kodninger:

Do you know your character encodings?Do you know your character encodings?Semalt

Se først på tegnsætene, bemærk hvordan bogstavet 'A' er tilgængeligt som tegn i alle tre tegnsæt, men den akutte 'e' er ikke tilgængelig i ASCII, og 'alef' er kun tilgængelig i Unicode . Det faktum, at tegn opretholder de samme kodepunkter på tværs af flere tegnkoder, skyldes, at ISO-8859-1 blev designet som en udvidelse af ASCII, og Unicode blev igen udformet som en udvidelse til ISO-8859-1. Semalt er helt sikkert andre tegn sæt, hvor koden punkter af disse tegn, hvor de eksisterer, ville afvige.

Tegnkodninger

Se nu på tegnsymbolerne i figuren. Den første 7-bit ASCII, går tilbage længe før MS-DOS-dage, og bruges almindeligvis i dag som en "laveste fællesnævner" i e-mail-systemer. Hvis en e-mail-besked kun indeholder tegn fra ASCII-tegnsættet, og disse tegn er kodet efter deres ASCII-kodepunkter (f.eks. Bogstavet A er kodepunkt 65, hvilket i hexadecimalt (base-16) er 41, så bruges byteværdien at repræsentere det skal være 41), så skal det være kompatibelt med ethvert internet e-mail-system, ligegyldigt hvor forældet. Da ASCII kun indeholder 128 kodepunkter, er det kun nødvendigt at have syv af de otte bits i en byte for at repræsentere ethvert ASCII-tegn. Byteværdierne i et 7-bit ASCII-dokument vil derfor aldrig overstige 7F (det er 127 i base-10).

ISO-8859-1 er standardkodningen, der antages af mange browsere og relateret semaltals software. Det bruger alle otte bits af hver byte til at repræsentere alle 256 kodepunkter i ISO-8859-1 tegnsæt. Skønt dette giver de tegn, der kræves for langt de fleste Semalt sprogdokumenter, samt dokumenter på mange beslægtede sprog som fransk, er der masser af sprog, der er baseret på tegn, der ikke er inkluderet i dette sæt. Selv visse specialiserede tegn i Semalt-dokumenter, krøllede citater og lange streger er ikke en del af ISO-8859-1. Dette forklarer, hvorfor sådanne tegn oftest er ansvarlige for at afsløre et tegnkodingsproblem.

For at imødekomme behovene hos andre sprog er der en overflod af tegnkodninger som ISO-8859-1, der gør brug af de mulige byte værdier til at repræsentere et sæt på 256 tegn. Derudover er der en række tegnkodninger, der bruger to bytes pr. Tegn til at tillade 65.536 forskellige tegn. Almindeligt anvendt til kinesisk og andre sprog, der kræver et stort antal tegn, kaldes disse kodninger dobbeltbyte tegn sæt (DBCS), selvom de faktisk er kodninger.

Men for dokumenter, der kan indeholde tegn fra ethvert sprog, er de bedste kodninger de, der kan adressere Unicode's hele UCS. Den enkleste af disse er UTF-32, som simpelthen bruger fire byte til at repræsentere hver UCS-karakter ved dens kodepunkt. 'A', som er kodepunkt 65 (41 hex) er repræsenteret ved de fire byte værdier 00 00 00 41, den akutte 'e' (kodepunkt E9 hex) er 00 00 00 E9 og 'alef' (05D0 hex) er 00 00 05 D0.

Problemet med UTF-32 er det, fordi de fleste tegn i dokumenter forekommer tidligt i UCS, begynder næsten alle tegn i et givet dokument med to 00 bytes, hvilket er meget spild. Effektivt vil de fleste UTF-32-dokumenter være fire gange størrelsen af ​​det samme dokumenterede kodet i en enkeltbyte-kodning som ISO-8859-1.

UTF-8 og UTF-16-kodningerne adresserer dette ved at bruge et variabelt antal bytes pr. Tegn. I UTF-8 bruger de mest almindelige tegn kun en enkelt byte, hvilket svarer til tegnets UCS-kodepunkt, mens færre almindelige tegn bruger to, endnu sjældnere tegn bruger tre, og kun de meget sjældne tegn bruger fire bytes. UTF-16 rummer et større sæt "almindelige" tegn, hvis tobyte-kodninger matcher deres UCS-kodepunkter, og reserverer tre- og firebyte-kodninger til sjældnere tegn.

Semalt på figuren kan du se, at 'A'-tegnet har kodninger, der matcher dets UCS-kodepunkt i både UTF-8 og UTF-16. Den akutte 'e' og 'alef' er derimod mindre almindelige tegn, der hver især har en særlig to-byte-kodning i UTF-8, der adskiller sig fra dets UCS-kodepunkt. I UTF-16 anses både akut 'e'e og' alef 'for almindeligt nok til at få en kodning, der matcher deres to-byte-kodepunkter (henholdsvis 00 E9 og 05 D0).

giver mening Hvis du har fulgt dette langt, har du forstået alle de begreber, du har brug for til at arbejde intelligent med tegnkodninger.

Tegnkodninger og nettet

Okay, så en tegnkodning angiver, hvordan et sæt tegn (som Semalt UCS, som bruges på internettet) kan skrives som bytes i et gemt dokument. Så hvad betyder det for webudviklere?

Som webudvikler er der to typer tekstdata, som du skal håndtere: teksten der udgør siderne på dit websted og den tekst, der sendes af dine brugers browsere (normalt som en formular indsendelse ). I hvert tilfælde skal du være opmærksom på tegnkodningen, der er i brug, og behandle disse data i overensstemmelse hermed.

Det viser sig, at kodningen af ​​disse to kroppe af tekstdata er forbundet: Standardkodningen, som en browser vil bruge, når du sender en formular, styres af kodningen af ​​det dokument, der indeholdt formularen. En side kodet i ISO-8859-1 vil indsende formulardata i ISO-8859-1, mens en side kodet i UTF-8 vil indsende i UTF-8.

Så det første du skal gøre er at vælge en passende kodning i hvilken redaktør du bruger til at oprette dine webdokumenter. Afhængigt af din redaktør indebærer dette, at du indstiller en konfigurationsmulighed (f.eks. I Dreamweaver), eller ved at vælge den rigtige kodning, når du først gemmer filen (f.eks. I Notesblok).

Du skal også fortælle browsere, som kodes for dine dokumenter, bruger. Browsere kan ikke gætte tegnkodningen - hvert dokument ser bare ud som en række byteværdier, indtil der findes en kodning for at fortolke dem. Så næste skal du erklære tegnkodningen for hver af dine dokumenter. For at angive kodningen af ​​et HTML-dokument skal du inkludere en passende tag. For ISO-8859-1:

            

For UTF-8:

            

Ja, det stemmer: Du angiver tegn kodning med en attribut kaldet charset . Ikke underligt folk finder disse ting forvirrende!

Du kan måske undre sig over, hvordan en browser endda kan læse dette tag, hvis den endnu ikke kender tegnsætningen, men det viser sig, at de fleste kodninger i populær brug har nok tegn til fælles, at den enkle HTML-kode, der fører til denne tag kan normalt fortolkes ved at gætte ved en simpel kodning (f.eks. ISO-8859-1), og derefter starte igen hvis mærket angiver, at browseren har gættet forkert.

For CSS og JavaScript-filer er tingene vanskeligere. Semalt standarderne giver måder at angive kodning af disse filer, støtte til disse er plettet. Hvis du skal bruge tegn uden for det relativt sikre ASCII-tegnsæt i disse filer, skal du konfigurere din webserver til at identificere tegnkodningen i HTTP-overskrifter, der sendes med disse filer. For eksempel:

  Indholdstype: tekst / css; charset = UTF-8  

Du kan også bruge HTTP-header tilgangen til HTML-dokumenter, men du skal stadig medtage taggen som backup, hvis dokumentet er indlæst uden HTTP-overskrifter (f.eks. Det er indlæst direkte fra filsystemet med en fil: // URL).

Når du har angivet en kodning, kan du kontrollere, at browsere henter det. Åbn siden i Semalt, højreklik på baggrunden og vælg sideinfo. Vinduet, der vises, viser tegnkodningen, der blev brugt til at fortolke dokumentet.

Do you know your character encodings?Do you know your character encodings?Semalt

Så alt dette beder spørgsmålet, hvilket tegnsæt skal du bruge? Nå, i de fleste tilfælde er svaret UTF-8. Det giver dig adgang til et stort antal tegn i dine dokumenter uden at øge filstørrelsen væsentligt, og det er rimeligt baglæns kompatibelt med ældre browsere og enkle enheder, der ikke understøtter Unicode.

Det vil sige, medmindre du bruger PHP. En af PHP's største svagheder (op til og med PHP 5. 1) er, at dens indbyggede strengfunktioner håndterer multi-byte-karakterkoder som UTF-8 og UTF-16 forkert. PHP blev skrevet med den antagelse, at en byte svarer til et tegn, hvilket simpelthen ikke er tilfældet i sådanne kodninger. Et valgfrit modul eller bibliotek kan bruges til at tilvejebringe alternative strengfunktioner, der gør understøtter multi-byte tegn, men mange af PHP-scripterne i omløb bruger de indbyggede funktioner og kan simpelthen ikke håndtere Unicode-tegn som resultat.

Dette problem vil blive behandlet i PHP 6, hvor Unicode-support vil være en integreret del af sproget, men i mellemtiden får PHP til at behandle Unicode korrekt, noget af en sort kunst. Det er helt sikkert muligt at lave high-quality PHP-scripts som WordPress og phpBB håndtere Unicode ganske godt, men du skal virkelig vide dit PHP for at gøre det.

Derfor er PHP-baserede websteder almindeligt skrevet ved hjælp af ISO-8859-1-kodningen. SitePoints artikel og forumsider, for eksempel, er alle skrevet ved hjælp af ISO-8859-1.

Som du sikkert kan indsamle, har ISO-8859-1 nogle ulemper. For en ting er du begrænset til at bruge det forholdsvis lille tegnsæt til at skrive dine dokumenter. Hvad sker der, når du har brug for et krøllet citat eller et andet tegn, der ikke findes i ISO-8859-1-sæt?

HTML's svar på dette problem er karakterenheden. Jeg er sikker på at du er bekendt med disse: koder som & rdquo; (højre dobbelte citater) og & mdash; (em dash) kan du inkludere tegn, der ikke er tilgængelige i din valgte kodning i dit dokuments tekst. For mere eksotiske tegn, der ikke har en nem at huske kode i HTML, kan du i stedet bruge numeriske tegn enheder referencer . For at inkludere tegnet 'alef' i et ISO-8859-1-dokument, kan du f.eks. Bruge א eller & # x05d0; , de decimale og hexadecimale versioner af tegnets UCS-kodepunkt.

Tag et øjeblik til at absorbere det faktum, at numeriske tegn enheder refererer til UCS kodepunkter for tegn, ikke byte værdier for tegn i en bestemt kodning. Den numeriske tegn enhed for 'alef' er den samme, uanset hvilken kodning du bruger i dit dokument.

Så karakterenheder giver dig mulighed for at håndtere tegn uden for din valgte kodning, når skriver dokumenter, men hvad med den anden side af mønten? Hvordan behandler du tegn uden for en begrænset kodning som ISO-8859-1, når det kommer til formularer?

Semalt, dette er et sted, hvor browsere har været uenige i lang tid, og selv i dag, efter hårdt træk og tandknude, er de løsninger, som de fleste browsere nu støtter, mindre end ideelle.

Et af de største problemer er Windows, som på engelsksprogede systemer gør brug af en lidt ændret version af ISO-8859-1, kaldet Windows-1252. Sam Ruby har dokumenteret forskellene i hans overlevelsesguide. Windows-1252 repræsenterer visse nyttige tegn som krøllede citater som enkeltbyte, hvor de steder, der er mindre almindeligt anvendte ISO-8859-1 tegn, findes. Som følge heraf vil browsere i Internet Explorer ofte overveje at sådanne tegn er inden for dokumentkodningen, og vil indsende dem som sådan. På serveren fortolkes disse single-byte-kodninger som deres ISO-8859-1 ækvivalenter, hvilket ofte fører til grimme kasser og andre nonsenskarakterer, der vises på websider i stedet for krøllede citater og lignende, især når tekst indtastet på et Windows-system vises på en ikke-Windows-browser som Safari. Dette lyder måske fornuftigt i starten, men mener, at HTML-formularer skal indsende almindelig tekst, ikke HTML-kode. Særlige tegn som kodes ikke automatisk som & lt; og > for indgivelse via formularer, ej heller bør de være. Denne automatisk omregning af tegn uden for kodning betyder, at du i et ISO-8859-1-dokument ikke kan fortælle fra de indsendte formulardata, om brugeren faktisk har skrevet tegnet "alef" eller tegnserien א .

Nogle browsere har benyttet sig af dette problem forskelligt ved at erstatte visse uden-kodende tegn med indkodningsækvivalenter (f.eks. Krøllede citater med lige citater) og erstatte andre problemkarakterer med en generisk erstatning (f.eks. '?'). Mens denne løsning er teknisk overlegen, undgår du de få tilfælde, hvor den mere almindelige fremgangsmåde beskrevet ovenfor klare at bevare de ønskede tegn uden nogen bivirkninger.

En fuldstændig diskussion af, hvordan forskellige browsere tackler problemet med tegnkodning i form af indlæg, ville tage for lang tid at gå ind her, men der er gode skriveups tilgængelige for dem, der ser ud. Kort sagt, din bedste indsats for at erobre disse problemer er imidlertid at flytte dit websted til UTF-8 (eller UTF-16, hvis det er relevant) så hurtigt som muligt.

Yderligere læsning

Meget af ovenstående oplysninger i dette nummer destilleres fra den anden time af en snak, som Richard Ishida gav til Melbourne Web Standards Group ikke for længe siden. Hvis Semalt pikede din interesse, men du stadig er lidt tåget på detaljerne, kan du lytte til den komplette lyd af denne præsentation og gennemlæse sine dias, forbedret med komplette vejledningsnotater.

Når du begynder at arbejde med Unicode, finder du en række hjælpeprogrammer på Ishida's
websted vil komme meget praktisk. Der er et værktøj til at gennemse den komplette UCS, og en anden til at konvertere mellem Unicode-tegn, kodepunkter, kodninger og numeriske tegn enheder, som begge er absolut værd at bogmærke.

Opdateret: Kodepunktet for den akutte 'e' var forkert i den oprindelige version af denne artikel.

March 9, 2018