UTF-8 (ang. 8-bit Unicode Transformation Format) – system kodowania Unicode, wykorzystujący od 1 do 4 bajtów do zakodowania pojedynczego znaku, w pełni kompatybilny z ASCII. Jest najczęściej wykorzystywany do przechowywania napisów w plikach i komunikacji sieciowej.
Zalety i wady
Zalety
- Każdy tekst w ASCII jest tekstem w UTF-8.
- Żaden znak spoza ASCII nie zawiera bajtu z ASCII.
- Zachowuje porządek sortowania UCS-4.
- Typowy tekst ISO-Latin-X rozrasta się w bardzo niewielkim stopniu po przekonwertowaniu do UTF-8.
- Nie zawiera bajtów 0xFF i 0xFE, więc łatwo można go odróżnić od tekstu UTF-16.
- Znaki o kodzie różnym od 0 nie zawierają bajtu 0, co pozwala stosować UTF-8 w ciągach zakończonych zerem.
- O każdym bajcie wiadomo, czy jest początkiem znaku, czy też leży w jego środku, co nie jest dostępne np. w kodowaniu EUC.
- Nie ma problemów z little endian vs big endian.
- Jest domyślnym kodowaniem w XML (również w jego aplikacjach: XHTML, SVG, XSL, CML, MathML).
Wady
- Znaki CJK zajmują po 3 bajty zamiast 2 w kodowaniach narodowych.
- Znaki alfabetów niełacińskich zajmują po 2 bajty zamiast jednego w kodowaniach narodowych.
- UTF-8 nie używa przesunięć zasięgów, co stanowi dodatkowe utrudnienie dla implementacji UTF-8 (szczegóły poniżej)
Sposób kodowania
Mapowanie znaków Unicode na ciągi bajtów możliwe jest na jeden z czterech sposobów:
U+00
do U+7F
– 0xxxxxxx
, gdzie kolejne „x
” to bity od najstarszego,
U+80
do U+7FF
– 110xxxxx 10xxxxxx
,
U+800
do U+FFFF
– 1110xxxx 10xxxxxx 10xxxxxx
,
U+10000
do U+10FFFF
– 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
.
Znaki z przedziału ASCII (0 do 127) kodowane są jako jeden bajt, czyli m.in. litery alfabetu łacińskiego. Polskie litery diakrytyzowane kodowane już są jako dwa bajty.
W listopadzie 2003 roku kodowanie UTF-8 zostało ograniczone zgodnie z RFC 3629 ↓, w celu zapewnienia zgodności z ograniczeniami kodowania UTF-16. Po pierwsze ograniczono maksymalny kod do U+10FFFF
. Wcześniej wynosił on U+7FFFFFFF
, dopuszczalne były sekwencje złożone z 5 i 6 bajtów, a 4-bajtowe mogły kodować znaki do U+1FFFFF
. Po drugie zabroniono kodów z zakresu od U+D800
do U+DFFF
, co pomniejszyło liczbę dopuszczalnych kodów o dodatkowe 2048. W ten sposób pozostało dokładnie 17 · 65536 − 2048 kodów, co oznacza że w UTF-8 można zakodować 1 112 064 różnych znaków.
Teoretycznie w UTF-8 ten sam znak można zapisać na kilka sposobów. Przykładowo znak ASCII /
(ukośnik) można by zapisać jako:
00101111
,
11000000 10101111
,
11100000 10000000 10101111
,
11110000 10000000 10000000 10101111
.
Stanowi to zagrożenie bezpieczeństwa m.in. dla serwerów, które sprawdzają obecność znaku /
w ścieżkach. Z tego powodu standard UTF-8 przewiduje, że poprawny jest wyłącznie najkrótszy możliwy sposób zapisu, a każdy program musi odrzucać znaki zapisane dłuższymi sekwencjami niż minimalna.
Przykład
Kodowanie na podstawie znaku euro €:
- Znak € w Unicode ma oznaczenie U+20AC.
- Zgodnie z informacjami w poprzednim podrozdziale taka wartość jest możliwa do zakodowania na 3 bajtach.
- Liczba szesnastkowa
20AC
to binarnie 0010 0000 1010 1100
po uzupełnieniu wiodącymi zerami do 16 bitów, ponieważ tyle bitów trzeba zakodować na 3 bajtach w UTF-8.
- Kodowanie na trzech bajtach wymaga użycia w pierwszym bajcie trzech wiodących bitów ustawionych na 1, a czwartego na 0 (
1110…
).
- Pozostałe bity pierwszego bajtu pochodzą z najstarszych czterech bitów kodowanej wartości w Unicode, co daje (
1110 0010
), a reszta bitów dzielona jest na dwa bloki po 6 bitów każdy (…0000 1010 1100
).
- Do tych bloków dodawane są wiodące bity
10
, by tworzyły następujące 8-bitowe wartości 1000 0010
i 1010 1100
).
- W ten sposób rezultatem są trzy bajty w postaci
1110 0010
1000 0010
1010 1100
, co w systemie szesnastkowych przyjmuje postać E2 82 AC
.
Poniższa tabela pozwala zrozumieć sposób kodowana różnej długości numerów kodowych Unicode w UTF-8.
Unicode
|
Unicode binarnie
|
UTF-8 binarnie
1. bajt 2. bajt 3. bajt 4. bajt
|
UTF-8 szesnastkowo
|
$ |
U+0024
|
0100100
|
00100100
|
24
|
¢ |
U+00A2
|
000 10100010
|
11000010 10100010
|
C2 A2
|
€ |
U+20AC
|
00100000 10101100
|
11100010 10000010 10101100
|
E2 82 AC
|
𐍈 |
U+10348
|
00001 00000011 01001000
|
11110000 10010000 10001101 10001000
|
F0 90 8D 88
|
Zobacz też
Linki zewnętrzne