UTF-8

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Unicode
Codificări
UCS
Cartografiere
Text bidirecțional
BOM
Unificarea Han
Unicode și HTML

UTF-8 (Unicode Transformation Format, 8 bit) este o codificare a caracterelor Unicode în secvențe de lungime de octeți variabilă, creată de Rob Pike și Ken Thompson . UTF-8 folosește grupuri de octeți pentru a reprezenta caracterele Unicode și este deosebit de util pentru transferul prin sisteme de poștă electronică pe 8 biți .

fundal

UTF-8 a fost conceput de Ken Thompson și Rob Pike la 2 septembrie 1992 pe un șervet într-un restaurant din New Jersey . A doua zi, Pike și Thompson l-au implementat și au actualizat Plan 9 , sistemul lor de operare , pentru al utiliza.

UTF-8 a fost prezentat oficial în ianuarie 1993 la San Diego la conferința anuală Usenix .

Caracteristici generale

UTF-8 folosește 1 până la 4 octeți pentru a reprezenta un caracter Unicode. De exemplu, este necesar un singur octet pentru a reprezenta cele 128 de caractere ale alfabetului ASCII , care corespund pozițiilor Unicode de la U + 0000 la U + 007F.

Patru octeți pot părea prea mult pentru un singur caracter; cu toate acestea, acest lucru este necesar numai pentru fonturile din afara planului de bază multilingv , care sunt în general foarte rare. În plus, UTF-16 (principala alternativă la UTF-8) necesită, de asemenea, patru octeți pentru aceste caractere. Ceea ce este mai eficient, UTF-8 sau UTF-16, depinde de gama de caractere utilizate, iar utilizarea algoritmilor tradiționali de compresie reduce semnificativ diferența dintre cele două codificări. Pentru bucăți scurte de text, unde algoritmii tradiționali de compresie sunt ineficienți și amprenta redusă a memoriei este importantă, ar putea fi folosit sistemul de compresie Unicode standard .

Internet Engineering Task Force ( IETF ) necesită ca toate protocoalele Internet să identifice codificarea caracterelor utilizate și să poată utiliza cel puțin UTF-8.

Descriere tehnica

UTF-8 este descris în standardul RFC 3629 ( UTF-8, un format de transformare ISO 10646 ). Pe scurt, biții care alcătuiesc un caracter Unicode sunt împărțiți în grupuri, care sunt apoi împărțiți între cei mai puțin semnificativi biți din octetii care alcătuiesc codarea UTF-8 a caracterului.

Caracterele a căror valoare unicode este mai mică decât U + 0080 sunt reprezentate cu un singur octet care conține valoarea lor; corespund exact celor 128 de caractere ASCII. În toate celelalte cazuri sunt necesare până la 4 octeți, fiecare dintre aceștia având bitul cel mai semnificativ setat la 1, pentru a le distinge de reprezentarea alfabetului ASCII pe 7 biți, în special a căror cod unicode este mai mic decât U + 0020, folosit în mod tradițional ca personaje de control.

Gama Unicode
hexazecimal
UTF-16 UTF-8
piese
Notă
0x000000-0x00007F 00000000 0XXXXXXX 0XXXXXXX Caracterele echivalente codului ASCII; octeții încep cu 0 și indică singuri un caracter
0x000080-0x0007FF 00000XXX XXXXXXXX 110XXXXX 10XXXXXX primul octet începe cu 110 sau 1110, următorul (i) cu 10 și trebuie concatenat pentru a forma un caracter
0x000800-0x00FFFF XXXXXXXX XXXXXXXX 1110XXXX 10XXXXXXX 10XXXXXX
0x010000-0x10FFFF 110110XX XXXXXXXX
110111XX XXXXXXXX
11110XXX 10XXXXXX 10XXXXXX 10XXXXXX Comparația dintre UTF-16 și UTF-8: UTF-16 necesită utilizarea perechilor surogate: se scade valoarea hexazecimală 0x10000, astfel încât secvența de biți să nu coincidă cu cea utilizată de UTF-8

De exemplu, caracterul alef (א), corespunzător Unicode U + 05D0, este reprezentat în UTF-8 cu această procedură:

  • se încadrează în intervalul de la 0x0080 la 0x07FF. Conform tabelului va fi reprezentat cu doi octeți (110XXXXX 10XXXXXX);
  • hexazecimal 0x05D0 este echivalent cu binarul 101-1101-0000;
  • unsprezece biți sunt copiați în ordine în pozițiile marcate cu „X”: 10- 110- 10111 010000;
  • rezultatul final este perechea de octeți 11010111 10010000 sau în hexazecimal 0xD7 0x90.

Pe scurt, primele 128 de caractere sunt reprezentate cu un singur octet. Anii 1920 de mai târziu necesită două și includ alfabete latine cu diacritice , greacă , chirilică , coptă , armeană , ebraică și arabă . Celelalte caractere din planul multilingv de bază au nevoie de trei octeți, restul de patru.

Potențial, UTF-8 ar putea utiliza secvențe de până la 6 octeți, acoperind intervalul de la U + 0000 la U + 7FFFFFFF (31 biți), dar în 2003 UTF-8 a fost limitat de standardul RFC 3629 pentru a acoperi doar „ interval descris formal în standardul Unicode, adică de la U + 0000 până la U + 10FFFF. Anterior, singurii octeți care nu puteau apărea într-o secvență UTF-8 validă erau 0xFE și 0xFF. Odată cu introducerea limitei de mai sus, numărul de octeți neutilizați de codificarea UTF-8 a crescut la 13: 0xC0, 0xC1 și de la 0xF5 la 0xFF. Deși noua definiție a UTF-8 limitează în mod constant setul de caractere Unicode care pot fi reprezentate, problema reprezentărilor multiple ale aceluiași caracter, un potențial risc de securitate, dispare deoarece fiecare dintre aceste secvențe ar conține unul dintre octeții neutilizați., rezultat invalid.

UTF-8 modificat

Limbajul de programare Java , care utilizează UTF-16 ca reprezentare internă a caracterelor, folosește o variantă non-standard a UTF-8 [1] pentru serializarea lor pe fișiere.

Există două diferențe între codificarea UTF-8 standard și cea modificată. Prima diferență este că caracterul nul (U + 0000) este reprezentat cu doi octeți în loc de unul, mai exact ca 11000000 10000000 (0xC0 0x80). Acest lucru asigură faptul că niciun șir codat nu este trunchiat prematur, deoarece conține octetul nul (0x00), care este interpretat de unele limbaje de programare (cum ar fi C ) ca un terminator de șir.

A doua diferență se referă la reprezentarea personajelor în afara BMP ( Basic Multilingual Plane ). Folosind UTF-8 standard, aceste caractere sunt reprezentate cu 4 octeți, conform formatului din tabelul anterior. Cu UTF-8 modificat, aceste caractere sunt mai întâi reprezentate ca perechi surogat (ca în UTF-16) și apoi ambele elemente ale perechii sunt codificate în UTF-8. Motivul acestei diferențe nu este evident. În Java, un caracter are 16 biți lungime, deci unele caractere Unicode trebuie reprezentate ca secvențe de două caractere. Acest aspect al limbajului este anterior introducerii planurilor suplimentare în Unicode, dar este important atât pentru factorii de performanță, cât și pentru compatibilitatea inversă și, prin urmare, este puțin probabil să fie remediat. Codificarea modificată asigură faptul că un șir codat poate fi decodat un caracter (16 biți) la un moment dat, mai degrabă decât un caracter Unicode la un moment dat. Din păcate, aceasta înseamnă că caracterele care necesită 4 octeți pentru a fi reprezentate în UTF-8 sunt reprezentate în UTF-8 modificat cu secvențe de 6 octeți.

Caracteristici ale UTF-8

Ca o consecință a mecanismelor de lucru ale UTF-8, secvențele de octeți se bucură de aceste proprietăți:

  • Cel mai semnificativ bit al oricărei secvențe de octeți este întotdeauna 0.
  • Cei mai semnificativi biți din primul dintr-o secvență de octeți multipli indică lungimea secvenței. Acești biți sunt 110 pentru secvențe de doi octeți și 1110 pentru secvențe de trei octeți.
  • Octetii care urmează primul dintr-o secvență constând din mai mulți octeți au întotdeauna 10 ca biți cei mai semnificativi.

UTF-8 a fost conceput pentru a satisface aceste trei proprietăți, asigurându-se că nici o secvență de octeți corespunzătoare unui caracter specific nu este conținută într-o secvență mai lungă, utilizată pentru a codifica un caracter diferit. Datorită acestei caracteristici, căutarea cuvintelor sau frazelor dintr-un text poate fi efectuată prin comparație octet cu octet; unele sisteme de codificare anterioare bazate pe secvențe de lungime variabilă a octeților (de exemplu Shift-JIS ) nu aveau această proprietate, făcând algoritmii de comparație a șirurilor complicate. Deși se poate susține că această caracteristică adaugă redundanță la codificarea textului, avantajele depășesc dezavantajele; în plus, compresia datelor nu este unul dintre scopurile UTF-8 și trebuie luată în considerare separat. În cele din urmă, din nou datorită acestei proprietăți, dacă unul sau mai mulți octeți s-au pierdut din cauza erorilor de transmisie sau corupției datelor, ar fi posibilă resincronizarea decodării la începutul următorului caracter, limitând daunele.

Formulare lungi, date nevalide și considerații de securitate

Comportamentul unui decodor în prezența intrării nevalide este aproape nedefinit. Există multe moduri în care un decodor poate reacționa la prezența intrării nevalide

  1. Introduceți un caracter pentru a-l înlocui pe cel nevalid (de ex. '?', ' ')
  2. Omiteți caracterul nevalid
  3. Interpretează personajul ca provenind dintr-un alt repertoriu de personaje (adesea latină-1 )
  4. Ignorați eroarea și continuați ca și cum caracterul ar arăta ca un cod UTF-8 valid
  5. Raportați o eroare

Decodificatoarele s-ar putea comporta, în mod evident, diferit atunci când se confruntă cu diferite tipuri de intrări nevalide.

Toate posibilitățile prezintă avantaje și dezavantaje, dar trebuie acordată o atenție specială siguranței dacă verificarea validității intrării se face înainte de convertirea din UTF-8.

Formele lungi (în care un caracter este codificat cu mai mulți octeți decât este strict necesar, dar întotdeauna în conformitate cu regulile anterioare) sunt unul dintre tipurile de intrare care prezintă mai multe probleme. Standardul actual impune ca aceste formulare să nu fie decodificate, dar specificațiile mai vechi erau limitate pentru a raporta problema, iar multe dintre cele mai simple decodificări continuă pentru decodificare fără niciun avertisment. Formularele lungi au fost folosite pentru a ocoli verificările de securitate în produsele de profil înalt, inclusiv serverul web Microsoft Internet Information Services (IIS)

Există două opțiuni pentru menținerea securității în caz de intrare nevalidă. Primul este decodarea codului UTF-8 înainte de a efectua toate verificările de validitate necesare la intrare . Al doilea este să folosiți un decodor mai rigid, care în cazul intrării nevalide returnează o eroare sau un text pe care aplicația îl consideră inofensiv.

Beneficii

  • Cel mai evident avantaj al oricărei codificări UTF este că permite reprezentarea tuturor caracterelor, spre deosebire de codificările mai vechi.
  • Unele caractere Unicode (de exemplu alfabetul latin) ocupă doar un octet în UTF-8, altele necesită până la patru octeți. În general, un text codat în UTF-8 va ocupa mai puțin spațiu decât UTF-16 sau UTF-32 corespunzător dacă conține multe caractere ASCII pe 7 biți.
  • O secvență de octeți care codifică un caracter nu poate apărea ca parte a unei secvențe mai lungi care codifică un alt caracter, așa cum a fost cazul codificărilor mai vechi cu lungime variabilă (vezi secțiunea anterioară).
  • Primul octet al unei secvențe este suficient pentru a determina lungimea acesteia (este suficient să se numere numărul celor mai semnificativi biți cu o valoare de unul). Acest lucru face foarte ușor extragerea unui șir dintr-un șir mai lung, fără a fi nevoie să decodezi secvența de octeți UTF-8.
  • Majoritatea software-urilor existente (inclusiv sistemele de operare ) au fost scrise fără a avea în vedere Unicode, iar utilizarea Unicode ar crea probleme de compatibilitate. De exemplu, biblioteca standard C marchează sfârșitul unui șir cu un octet nul (0x00). Folosind UTF-16, caracterul Unicode „A” va fi codat ca 0x0041. Primul octet va fi tratat ca un marker de sfârșit de șir, iar al doilea și toate cele ulterioare vor fi ignorate. UTF-8 este conceput astfel încât niciunul dintre octeții codificați să nu poată prelua niciuna dintre valorile speciale ale codului ASCII, evitând acest lucru și probleme similare.
  • UTF-8 este codificarea implicită pentru formatul XML .

Dezavantaje

  • UTF-8 folosește secvențe de lungime variabilă, adică diferite caractere sunt reprezentate cu secvențe de octeți de lungimi diferite. Cu toate acestea, severitatea problemei ar putea fi limitată prin crearea unei interfețe abstracte care funcționează cu șiruri UTF-8 și o face complet transparentă pentru utilizator. Mai mult, UTF-16 folosește, de asemenea, secvențe de lungime variabilă, deși mulți nu știu acest lucru (sau nu sunt interesați de caractere în afara planului de bază multilingv ).
  • Un decodor slab programat (și care nu este conform cu cele mai recente versiuni ale standardului) ar putea accepta mai multe pseudo-codificări UTF-8 și le poate converti în același caracter Unicode, ocolind astfel orice verificări de securitate concepute pentru a funcționa pe reprezentări de date pe 8 biți.
  • Ideogramele sunt reprezentate în UTF-8 cu trei octeți, în timp ce necesită doar două în UTF-16. Drept urmare, textele chinezești / japoneze / coreene , precum și unele grupuri de caractere Unicode mai puțin cunoscute, ocupă mai mult spațiu atunci când sunt codificate cu UTF-8.

Notă

  1. ^ Documentația java.io.DataInput , secțiunea "UTF-8 modificat" , la download.oracle.com . Adus la 4 mai 2011 .

Elemente conexe

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT