UTF-8
Standard | Standard Unicode |
---|---|
Klasyfikacja | Format transformacji Unicode , rozszerzony ASCII , kodowanie o zmiennej długości |
rozciąga się | US-ASCII |
Transformuje / koduje | ISO/IEC 10646 ( Unicode ) |
Poprzedzony | UTF-1 |
UTF-8 to standard kodowania znaków o zmiennej długości używany w komunikacji elektronicznej. Zdefiniowana przez standard Unicode , nazwa pochodzi od formatu transformacji Unicode (lub uniwersalnego zestawu kodowanych znaków ) — 8-bitowy .
UTF-8 jest w stanie zakodować wszystkie 1 112 064 ważnych punktów kodowych znaków w Unicode przy użyciu od jednej do czterech jednobajtowych (8-bitowych) jednostek kodu. Punkty kodowe o niższych wartościach liczbowych, które występują częściej, są kodowane przy użyciu mniejszej liczby bajtów. Został zaprojektowany z myślą o wstecznej kompatybilności z ASCII : pierwsze 128 znaków Unicode, które odpowiadają ASCII jeden do jednego, jest kodowanych przy użyciu pojedynczego bajtu z tą samą wartością binarną co ASCII, dzięki czemu prawidłowy tekst ASCII jest prawidłowym kodem UTF-8 - zakodowany również Unicode.
UTF-8 został zaprojektowany jako doskonała alternatywa dla UTF-1 , proponowanego kodowania o zmiennej długości z częściową kompatybilnością z ASCII, któremu brakowało niektórych funkcji, w tym samosynchronizacji i w pełni zgodnej z ASCII obsługi znaków, takich jak ukośniki. Ken Thompson i Rob Pike opracowali pierwszą implementację dla systemu operacyjnego Plan 9 we wrześniu 1992 roku. Doprowadziło to do przyjęcia jej przez X/Open jako specyfikacji dla FSS-UTF , która po raz pierwszy została oficjalnie zaprezentowana na USENIX w styczniu 1993 r., a następnie przyjęty przez Internet Engineering Task Force (IETF) w dokumencie RFC 2277 ( BCP 18 ) do przyszłych prac nad standardami internetowymi, zastępując zestawy znaków jednobajtowych, takie jak Latin-1, w starszych dokumentach RFC.
UTF-8 powoduje mniej problemów związanych z internacjonalizacją niż jakiekolwiek alternatywne kodowanie tekstu i został zaimplementowany we wszystkich nowoczesnych systemach operacyjnych , w tym Microsoft Windows , oraz w standardach takich jak JSON , gdzie, jak to ma miejsce w coraz większym stopniu, jest jedyną dozwoloną formą Unikod .
UTF-8 jest dominującym kodowaniem w sieci World Wide Web (i technologiach internetowych), stanowiącym 97,9% wszystkich stron internetowych, ponad 99,0% z 10 000 najpopularniejszych stron i do 100,0% dla wielu języków od 2023 r. Praktycznie wszystkie kraje i języki mają 95,0% lub więcej wykorzystania kodowania UTF-8 w Internecie.
Nazewnictwo
Oficjalna nazwa kodowania to UTF-8 , pisownia używana we wszystkich dokumentach Konsorcjum Unicode. Większość standardów wymienia to oficjalnie wielkimi literami w ten sposób, a wszystkie, które to robią, nie uwzględniają wielkości liter, a najczęściej utf-8
jest używany w kodzie (ponieważ jest łatwiejszy do pisania). Dzieje się tak pomimo tego, że oficjalne wielkie litery są odpowiednie dla akronimu.
Niektóre inne pisownie mogą być również akceptowane przez standardy, np. standardy sieciowe (które obejmują nagłówki CSS , HTML , XML i HTTP ) jawnie zezwalają na utf8 (i nie zezwalają na „unicode”) i wiele aliasów dla kodowania). Nie należy używać pisowni ze spacją, np. „UTF 8”. Oficjalny Internet Assigned Numbers Authority wymienia również csUTF8 jako jedyny alias, który jest rzadko używany.
W systemie Windows UTF-8 to strona kodowa 65001
(tj. CP_UTF8
w kodzie źródłowym).
W MySQL UTF-8 nazywa się utf8mb4
(z utf8mb3
i jego aliasem utf8
, będącym podzbiorem kodowania znaków w Basic Multilingual Plane ). W HP PCL identyfikator symbolu dla UTF-8 to 18N
.
W Oracle Database (od wersji 9.0) AL32UTF8
oznacza UTF-8. Zobacz także CESU-8 , aby znaleźć prawie synonim UTF-8, który rzadko powinien być używany.
UTF-8-BOM i UTF-8-NOBOM są czasami używane w przypadku plików tekstowych, które odpowiednio zawierają lub nie zawierają znacznika kolejności bajtów (BOM). [ wymagane źródło ] Szczególnie w Japonii kodowanie UTF-8 bez BOM jest czasami nazywane UTF-8N .
Kodowanie
UTF-8 koduje punkty kodowe w jednym do czterech bajtów, w zależności od wartości punktu kodowego. W poniższej tabeli x są zastępowane bitami punktu kodowego:
Pierwszy punkt kodu | Ostatni punkt kodu | Bajt 1 | Bajt 2 | Bajt 3 | Bajt 4 | Punkty kodowe |
---|---|---|---|---|---|---|
U+0000 | U+007F | 0xxxxxxx | 128 | |||
U+0080 | U+07FF | 110xxxxx | 10xxxxxx | 1920 | ||
U+0800 | U+FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | 61440 | |
U+10000 | U+10FFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 1048576 |
Pierwsze 128 punktów kodowych (ASCII) wymaga jednego bajtu. Kolejne 1920 punktów kodowych potrzebuje dwóch bajtów do zakodowania, co obejmuje pozostałą część prawie wszystkich alfabetów łacińskich , a także rozszerzenia IPA , grecki , cyrylicę , koptyjski , ormiański , hebrajski , arabski , syryjski , Thaana i N'Ko , jak jak również łączenie znaków diakrytycznych . Dla reszty potrzebne są trzy bajty Basic Multilingual Plane (BMP), który zawiera praktycznie wszystkie powszechnie używane punkty kodowe, w tym większość znaków chińskich, japońskich i koreańskich . Potrzebne są cztery bajty dla punktów kodowych w innych płaszczyznach Unicode , które obejmują mniej popularne znaki CJK , różne historyczne skrypty, symbole matematyczne i emotikony (symbole piktograficzne).
„Znak” może zająć więcej niż 4 bajty, ponieważ składa się z więcej niż jednego punktu kodowego. Na przykład znak flagi narodowej zajmuje 8 bajtów, ponieważ jest „skonstruowany z pary wartości skalarnych Unicode”, zarówno spoza BMP.
Przykłady
W tych przykładach cyfry czerwona, zielona i niebieska wskazują, w jaki sposób bity z punktu kodowego są rozdzielane między bajty UTF-8. Dodatkowe bity dodane przez proces kodowania UTF-8 są pokazane na czarno.
- Punkt kodowy Unicode dla znaku euro € to U+20AC.
- Ponieważ ten punkt kodowy znajduje się między U+0800 a U+FFFF, zakodowanie zajmie trzy bajty.
- Szesnastkowy 20AC to binarny 0010 0000 10 10 1100 . Dwa wiodące zera są dodawane, ponieważ kodowanie trzybajtowe wymaga dokładnie szesnastu bitów od punktu kodowego.
- Ponieważ kodowanie będzie miało długość trzech bajtów, jego wiodący bajt zaczyna się od trzech jedynek, a następnie 0 ( 1110... )
- Cztery najbardziej znaczące bity punktu kodowego są przechowywane w pozostałych czterech najmłodszych bitach tego bajtu ( 1110 0010 ), pozostawiając 12 bitów punktu kodowego do zakodowania ( ... 0000 10 10 1100 ).
- Wszystkie bajty kontynuacji zawierają dokładnie sześć bitów od punktu kodowego. Tak więc następne sześć bitów punktu kodowego jest zapisywanych w młodszych bitach następnego bajtu, a 10 jest zapisywanych w dwóch bitach wyższego rzędu, aby oznaczyć go jako bajt kontynuacji (więc 10 000010 ).
- Na koniec ostatnie sześć bitów punktu kodowego jest zapisywanych w młodszych sześciu bitach ostatniego bajtu, a ponownie 10 jest zapisywanych w dwóch bitach wyższego rzędu ( 10 101100 ).
Trzy bajty 1110 0010 10 000010 10 101100 można zapisać bardziej zwięźle szesnastkowo , jako E2 82 AC .
Poniższa tabela podsumowuje tę konwersję, a także inne o różnych długościach w UTF-8.
Postać | Punkt kodu binarnego | Binarny UTF-8 | Szesnastkowy UTF-8 | |
---|---|---|---|---|
$ | U+0024 | 010 0100 | 00100100 | 24 |
£ | U+00A3 | 000 10 10 0011 | 110 00010 10 100011 | C2 A3 |
ह | U+0939 | 0000 1001 00 11 1001 | 1110 0000 10 100100 10 111001 | E0 A4 B9 |
€ | U+20AC | 0010 0000 10 10 1100 | 1110 0010 10 000010 10 101100 | E2 82 AC |
한 | U+D55C | 1101 0101 01 01 1100 | 1110 1101 10 010101 10 011100 | ED 95 9C |
𐍈 | U+10348 | 0 00 01 0000 0011 01 00 1000 | 11110 000 10 010000 10 001101 10 001000 | F0 90 8D 88 |
ósemkowy
Użycie przez UTF-8 sześciu bitów na bajt do reprezentowania rzeczywistych kodowanych znaków oznacza, że notacja ósemkowa (wykorzystująca grupy 3-bitowe) może pomóc w porównywaniu sekwencji UTF-8 między sobą oraz w ręcznej konwersji.
Pierwszy punkt kodu | Ostatni punkt kodu | Punkt kodu | Bajt 1 | Bajt 2 | Bajt 3 | Bajt 4 |
---|---|---|---|---|---|---|
000 | 0177 | xxx | xxx | |||
0200 | 03777 | xxyy | 3xx | 2rr | ||
04000 | 077777 | xyyzz | 34x | 2rr | 2zz | |
0100000 | 0177777 | 1xyyzz | 35x | 2rr | 2zz | |
0200000 | 04177777 | xyyzzww | 36x | 2rr | 2zz | 2ww |
W notacji ósemkowej dowolne cyfry ósemkowe, oznaczone w tabeli jako x, y, z lub w, pozostaną niezmienione podczas konwersji do lub z UTF-8.
- Przykład: Á = U+00C1 = 0301 (w systemie ósemkowym) jest zakodowane jako 303 201 w UTF-8 (C3 81 w systemie szesnastkowym).
- Przykład: € = U+20AC = 020254 jest zakodowane jako 342 202 254 w UTF-8 (E2 82 AC w formacie szesnastkowym).
Układ strony kodowej
Poniższa tabela podsumowuje użycie jednostek kodu UTF-8 (pojedynczych bajtów lub oktetów ) w formacie strony kodowej . Górna połowa jest przeznaczona na bajty używane tylko w kodach jednobajtowych, więc wygląda jak normalna strona kodowa; dolna połowa dotyczy bajtów kontynuacji i bajtów wiodących i jest wyjaśniona w poniższej legendzie.
UTF-8 | ||||||||||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | mi | F | |
0x | NUL | SOH | STX | ETX | OT | ENQ | POK | BEL | BS | HT | LF | VT | FF | CR | WIĘC | SI |
1x | DLE | DC1 | ST2 | DC3 | DC4 | NAK | SYN | ETB | MÓC | EM | POD | WYJŚCIE | FS | GS | RS | NAS |
2x | Sp | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / |
3x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
4x | @ | A | B | C | D | mi | F | G | H | I | J | k | Ł | M | N | O |
5x | P | Q | R | S | T | u | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
6x | ` | A | B | C | D | mi | F | G | H | I | J | k | l | M | N | o |
7x | P | Q | R | S | T | u | w | w | X | y | z | { | | | } | ~ | DEL |
8x | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • |
9x | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • |
Topór | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • |
Bx | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • | • |
Cx | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Dx | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
Były | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
Fx | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 5 | 5 | 5 | 5 | 6 | 6 |
Zbyt długie kodowanie
Zasadniczo możliwe byłoby zawyżenie liczby bajtów w kodowaniu przez wypełnienie punktu kodowego wiodącymi zerami. Aby zakodować znak euro € z powyższego przykładu w czterech bajtach zamiast trzech, można go uzupełnić wiodącymi zerami, aż będzie miał długość 21 bitów – 000 000010 000010 101100 i zakodowany jako 11110 000 10 000010 10 000010 10 101100 (lub F0 82 82 AC w systemie szesnastkowym). Nazywa się to zbyt długim kodowaniem .
Standard określa, że prawidłowe kodowanie punktu kodowego wykorzystuje tylko minimalną liczbę bajtów wymaganych do przechowywania znaczących bitów punktu kodowego. Dłuższe kodowania nazywane są overlongami i nie są prawidłowymi reprezentacjami punktu kodowego w UTF-8. Ta reguła utrzymuje zgodność jeden-do-jednego między punktami kodowymi i ich prawidłowymi kodowaniami, dzięki czemu dla każdego punktu kodowego istnieje unikatowe prawidłowe kodowanie. Zapewnia to, że porównania ciągów i wyszukiwania są dobrze zdefiniowane.
Nieprawidłowe sekwencje i obsługa błędów
Nie wszystkie sekwencje bajtów są poprawne w formacie UTF-8. Dekoder UTF-8 powinien być przygotowany na:
- nieprawidłowe bajty
- nieoczekiwany bajt kontynuacji
- bajt niebędący kontynuacją przed końcem znaku
- ciąg kończący się przed końcem znaku (co może się zdarzyć w przypadku prostego obcięcia łańcucha)
- zbyt długie kodowanie
- sekwencja, która dekoduje do nieprawidłowego punktu kodowego
Wiele z pierwszych dekoderów UTF-8 dekodowało je, ignorując nieprawidłowe bity i akceptując zbyt długie wyniki. Starannie spreparowany nieprawidłowy kod UTF-8 może spowodować pominięcie lub utworzenie znaków ASCII, takich jak NUL, ukośnik lub cudzysłowy. Nieprawidłowy kod UTF-8 był używany do obejścia sprawdzania poprawności zabezpieczeń w produktach o wysokim profilu, w tym w IIS firmy Microsoft i kontenerze serwletów Tomcat firmy Apache. RFC 3629 stwierdza: „Implementacje algorytmu dekodowania MUSZĄ chronić przed dekodowaniem nieprawidłowych sekwencji”. Standard Unicode wymaga, aby dekodery „... traktowały każdą źle sformułowaną sekwencję jednostek kodu jako warunek błędu. Gwarantuje to, że nie zinterpretuje ani nie wyemituje źle sformułowanej sekwencji jednostek kodu”.
Od RFC 3629 (listopad 2003) wysokie i niskie zastępcze połówki używane przez UTF-16 (od U + D800 do U + DFFF) oraz punkty kodowe niekodowane przez UTF-16 (te po U + 10FFFF) nie są legalnymi wartościami Unicode, a ich kodowanie UTF-8 musi być traktowane jako nieprawidłowa sekwencja bajtów. Brak dekodowania niesparowanych połówek zastępczych uniemożliwia przechowywanie nieprawidłowego UTF-16 (takiego jak nazwy plików systemu Windows lub UTF-16, który został podzielony między surogaty) jako UTF-8, podczas gdy jest to możliwe w przypadku WTF- 8 .
Niektóre implementacje dekoderów zgłaszają wyjątki w przypadku błędów. Ma to tę wadę, że może zmienić nieszkodliwe błędy (takie jak błąd „brak takiego pliku”) w odmowę usługi . Na przykład wczesne wersje Pythona 3.0 zamykały się natychmiast, jeśli wiersz poleceń lub zmienne środowiskowe zawierały nieprawidłowy kod UTF-8. Alternatywną praktyką jest zastępowanie błędów znakiem zastępczym. Od Unicode 6 (październik 2010) standard ( rozdział 3 ) zaleca „najlepszą praktykę”, w której błąd kończy się, gdy tylko napotkany zostanie niedozwolony bajt. W tych dekoderach E1,A0,C0 to dwa błędy (2 bajty w pierwszym). Oznacza to, że błąd ma długość nie większą niż trzy bajty i nigdy nie zawiera początku prawidłowego znaku, a możliwych błędów jest 21 952. Norma zaleca również zastąpienie każdego błędu znakiem zastępczym „�” (U+FFFD).
Znacznik kolejności bajtów
Jeśli znak kolejności bajtów Unicode (BOM, U+FEFF) znajduje się na początku pliku UTF-8, pierwsze trzy bajty będą miały postać 0xEF , 0xBB , 0xBF .
Standard Unicode nie wymaga ani nie zaleca używania BOM dla UTF-8, ale ostrzega, że można go napotkać na początku pliku transkodowanego z innego kodowania. Chociaż tekst ASCII zakodowany przy użyciu UTF-8 jest wstecznie zgodny z ASCII, nie jest to prawdą, gdy zalecenia standardu Unicode są ignorowane i dodawane jest zestawienie komponentów. BOM może mylić oprogramowanie, które nie jest do tego przygotowane, ale może w inny sposób akceptować UTF-8, np. języki programowania, które zezwalają na bajty inne niż ASCII w literałach łańcuchowych ale nie na początku pliku. Niemniej jednak istniało i nadal istnieje oprogramowanie, które zawsze wstawia BOM podczas zapisywania UTF-8 i odmawia poprawnej interpretacji UTF-8, chyba że pierwszym znakiem jest BOM (lub plik zawiera tylko ASCII).
Przyjęcie
Większość systemów operacyjnych, w tym Windows, obsługuje UTF-8.
Wiele standardów obsługuje tylko UTF-8, np. wymaga tego wymiana JSON (bez znacznika kolejności bajtów (BOM)). UTF-8 jest również zaleceniem WHATWG dla specyfikacji HTML i DOM , i stwierdza, że „Kodowanie UTF-8 jest najodpowiedniejszym kodowaniem do wymiany Unicode ”, a Internet Mail Consortium zaleca, aby wszystkie programy pocztowe mogły wyświetlać i twórz pocztę przy użyciu UTF-8. Konsorcjum World Wide Web zaleca UTF-8 jako domyślne kodowanie w XML i HTML (a nie tylko używanie UTF-8, również deklarowanie go w metadanych), „nawet jeśli wszystkie znaki są w zakresie ASCII… Używanie kodowania innego niż UTF-8 może mieć nieoczekiwane rezultaty".
UTF-8 jest najpopularniejszym kodowaniem w sieci World Wide Web od 2008 r. Od marca 2023 r. UTF-8 stanowi średnio 97,9% (wcześniej do 98,0%) wszystkich stron internetowych (i 99,1% z 10 000 najlepszych stron i 98,6% z 1000 najwyżej ocenianych stron internetowych. Chociaż wiele stron używa tylko znaków ASCII do wyświetlania treści, niewiele witryn deklaruje teraz, że ich kodowanie to tylko ASCII zamiast UTF-8. Ponad 45% śledzonych języków ma 100% UTF -8 użycia.
Wiele programów ma możliwość odczytu/zapisu UTF-8, a czasami (nawet w niektórych produktach Microsoft) UTF-8 jest jedyną opcją. Może to jednak wymagać od użytkownika zmiany opcji z normalnych ustawień lub może wymagać BOM (znaku kolejności bajtów) jako pierwszego znaku do odczytania pliku. Przykłady oprogramowania obsługującego UTF-8 to Microsoft Word , Microsoft Excel (2016 i nowsze), Dysk Google i LibreOffice . Większość baz danych może odczytywać i zapisywać UTF-8.
do pewnego stopnia pozostaje w użyciu kilka starszych kodowań jednobajtowych (i kilka wielobajtowych CJK ). Główną przyczyną tego są edytory tekstu, które odmawiają używania UTF-8 podczas przetwarzania plików, chyba że pierwsze bajty pliku kodują znak kolejności bajtów (BOM). Wiele innych edytorów tekstu po prostu zakłada kodowanie UTF-8 dla wszystkich plików ze względu na jego niemal wszechobecność . Ponieważ Windows 10 Notatnik Windows domyślnie pisze UTF-8 bez BOM (zmiana od Windows 7 ), dostosowując go do większości innych edytorów tekstu. Niektóre pliki systemowe w systemie Windows 11 wymagają UTF-8 bez wymogu BOM, a prawie wszystkie pliki w systemach macOS i Linux muszą być w formacie UTF-8 bez BOM. [ potrzebne źródło ] Java 18 domyślnie odczytuje i zapisuje pliki w UTF-8, aw starszych wersjach (np. wersjach LTS ) zmieniono w tym celu tylko NIO API. Wiele innych języków programowania domyślnie używa UTF-8 dla wejścia/wyjścia , w tym Ruby 3.0 i R 4.2.2. Wszystkie obecnie obsługiwane wersje Python obsługuje UTF-8 dla we/wy, nawet w systemie Windows (gdzie funkcja open()
jest opcjonalna ) i istnieją plany, aby UTF-8 we/wy był domyślny w Pythonie 3.15 na wszystkich platformach.
Wykorzystanie UTF-8 w oprogramowaniu jest również niższe niż w innych obszarach ( zamiast tego często używany jest UTF-16 ). Dzieje się tak zwłaszcza w systemie Windows, ale także w JavaScript , Python, Qt i wielu innych międzyplatformowych bibliotekach oprogramowania. Głównym tego powodem jest zgodność z interfejsem API systemu Windows , chociaż czynnikiem było również przekonanie, że bezpośrednie indeksowanie BMP poprawia szybkość. Nowsze oprogramowanie zaczęło używać prawie wyłącznie UTF-8: domyślny łańcuch pierwotny w Go , Julia , Rust , Swift 5 , a PyPy używa UTF-8; planowana jest przyszła wersja Pythona do przechowywania łańcuchów jako UTF-8; a nowoczesne wersje Microsoft Visual Studio używają wewnętrznie UTF-8. Microsoft SQL Server 2019 dodał obsługę UTF-8, a użycie go skutkuje 35% wzrostem prędkości i „prawie 50% zmniejszeniem wymagań dotyczących pamięci”. UTF-8 to „jedyne kodowanie tekstu, które musi być obsługiwane przez standard C++” w C++20 . C++23 przyjmuje UTF-8 jako jedyny przenośny format pliku kodu źródłowego (co zaskakujące, wcześniej go nie było).
Wszystkie obecnie obsługiwane wersje systemu Windows obsługują w jakiś sposób UTF-8 (w tym Xbox ); częściowe wsparcie istnieje przynajmniej od czasu Windows XP . Od maja 2019 r. Microsoft zmienił swoje poprzednie stanowisko i zalecał tylko UTF-16; wprowadzono możliwość ustawienia UTF-8 jako „strony kodowej” dla Windows API; a Microsoft zaleca programistom używanie UTF-8, a nawet stwierdza, że „UTF-16 […] to wyjątkowe obciążenie, jakie system Windows nakłada na kod przeznaczony dla wielu platform”.
Historia
Międzynarodowa Organizacja Normalizacyjna (ISO) postanowiła stworzyć uniwersalny wielobajtowy zestaw znaków w 1989 r. Projekt normy ISO 10646 zawierał niewymagany załącznik o nazwie UTF-1, który zapewniał kodowanie strumienia bajtów jego 32-bitowych punktów kodowych . To kodowanie nie było zadowalające między innymi ze względu na wydajność, a największym problemem był prawdopodobnie brak wyraźnego oddzielenia ASCII od nie-ASCII: nowe narzędzia UTF-1 byłyby wstecznie kompatybilne z tekstem zakodowanym w ASCII, ale Tekst zakodowany w UTF-1 może zmylić istniejący kod oczekujący ASCII (lub rozszerzonego ASCII ), ponieważ mógł zawierać bajty kontynuacji z zakresu 0x21–0x7E, które oznaczały coś innego w ASCII, np. 0x2F dla „/”, separator katalogów ścieżki systemu Unix , a ten przykład znajduje odzwierciedlenie w nazwie i tekście wprowadzającym jego zamiennika. Poniższa tabela pochodzi z opisu tekstowego w załączniku.
Liczba bajtów |
Pierwszy punkt kodu |
Ostatni punkt kodu |
Bajt 1 | Bajt 2 | Bajt 3 | Bajt 4 | Bajt 5 |
---|---|---|---|---|---|---|---|
1 | U+0000 | U+009F | 00–9F | ||||
2 | U+00A0 | U+00FF | A0 | A0–FF | |||
2 | U+0100 | U+4015 | A1–F5 | 21–7E, A0–FF | |||
3 | U+4016 | U+38E2D | F6–FB | 21–7E, A0–FF | 21–7E, A0–FF | ||
5 | U+38E2E | U+7FFFFFFFF | FC–FF | 21–7E, A0–FF | 21–7E, A0–FF | 21–7E, A0–FF | 21–7E, A0–FF |
W lipcu 1992 roku komitet X/Open XoJIG szukał lepszego kodowania. Dave Prosser z Unix System Laboratories przedstawił propozycję rozwiązania, które miałoby szybszą implementację i wprowadziło ulepszenie polegające na tym, że 7-bitowe znaki ASCII reprezentowałyby tylko siebie; wszystkie sekwencje wielobajtowe zawierałyby tylko bajty, w których ustawiono wysoki bit. Nazwa File System Safe UCS Transformation Format (FSS-UTF) i większość tekstu tej propozycji zostały później zachowane w ostatecznej specyfikacji.
FSS-UTF
Liczba bajtów |
Pierwszy punkt kodu |
Ostatni punkt kodu |
Bajt 1 | Bajt 2 | Bajt 3 | Bajt 4 | Bajt 5 |
---|---|---|---|---|---|---|---|
1 | U+0000 | U+007F | 0xxxxxxx | ||||
2 | U+0080 | U+207F | 10xxxxxx | 1xxxxxxx | |||
3 | U+2080 | U+8207F | 110xxxxx | 1xxxxxxx | 1xxxxxxx | ||
4 | U+82080 | U+208207F | 1110xxxx | 1xxxxxxx | 1xxxxxxx | 1xxxxxxx | |
5 | U+2082080 | U+7FFFFFFFF | 11110xxx | 1xxxxxxx | 1xxxxxxx | 1xxxxxxx | 1xxxxxxx |
IBM X/Open rozesłał tę propozycję zainteresowanym stronom. Modyfikacja dokonana przez Kena Thompsona z grupy systemów operacyjnych Plan 9 w Bell Labs spowodowała samosynchronizację , pozwalając czytelnikowi rozpocząć w dowolnym miejscu i natychmiast wykryć granice znaków, kosztem nieco mniejszej wydajności bitowej niż poprzednia propozycja. Zrezygnowano również ze stosowania uprzedzeń i zamiast tego dodano zasadę, że dozwolone jest tylko najkrótsze możliwe kodowanie; dodatkowa utrata zwartości jest stosunkowo niewielka, ale czytelnicy muszą teraz zwracać uwagę na nieprawidłowe kodowanie, aby uniknąć problemów z niezawodnością, a zwłaszcza z bezpieczeństwem. Projekt Thompsona został nakreślony 2 września 1992 roku na a podkładka pod talerz w restauracji w New Jersey z Robem Pikiem . W następnych dniach Pike i Thompson wdrożyli go i zaktualizowali Plan 9 , aby używać go przez cały czas, a następnie poinformowali o swoim sukcesie z powrotem do X/Open, który zaakceptował go jako specyfikację dla FSS-UTF.
Liczba bajtów |
Pierwszy punkt kodu |
Ostatni punkt kodu |
Bajt 1 | Bajt 2 | Bajt 3 | Bajt 4 | Bajt 5 | Bajt 6 |
---|---|---|---|---|---|---|---|---|
1 | U+0000 | U+007F | 0xxxxxxx | |||||
2 | U+0080 | U+07FF | 110xxxxx | 10xxxxxx | ||||
3 | U+0800 | U+FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |||
4 | U+10000 | U+1FFFFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | ||
5 | U+200000 | U+3FFFFFF | 111110xx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | |
6 | U+4000000 | U+7FFFFFFFF | 1111110x | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
UTF-8 został po raz pierwszy oficjalnie zaprezentowany na konferencji USENIX w San Diego w dniach 25-29 stycznia 1993 r. Internet Engineering Task Force przyjęła UTF-8 w swojej Polityce dotyczącej zestawów znaków i języków w RFC 2277 ( BCP 18) dla przyszłego Internetu działają standardy, zastępując zestawy znaków jednobajtowych, takie jak Latin-1 w starszych dokumentach RFC.
W listopadzie 2003 r. UTF-8 został ograniczony przez RFC 3629 , aby dopasować się do ograniczeń kodowania znaków UTF-16 : wyraźny zakaz punktów kodowych odpowiadających wysokim i niskim znakom zastępczym usunięto ponad 3% sekwencji trzybajtowych i kończąc w U + 10FFFF usunięto ponad 48% sekwencji czterobajtowych oraz wszystkie sekwencje pięcio- i sześciobajtowe.
Normy
Istnieje kilka aktualnych definicji UTF-8 w różnych dokumentach norm:
- RFC 3629 / STD 63 (2003), który ustanawia UTF-8 jako standardowy element protokołu internetowego
- RFC 5198 definiuje UTF-8 NFC dla Network Interchange (2008)
- ISO/IEC 10646:2014 §9.1 (2014)
- Standard Unicode, wersja 14.0.0 (2021)
Zastępują one definicje podane w następujących przestarzałych pracach:
- Standard Unicode, wersja 2.0 , dodatek A (1996)
- ISO/IEC 10646-1:1993 Poprawka 2 / Załącznik R (1996)
- Dokument RFC 2044 (1996)
- Dokument RFC 2279 (1998)
- Standard Unicode, wersja 3.0 , §2.3 (2000) plus sprostowanie nr 1: Najkrótszy formularz UTF-8 (2000)
- Załącznik nr 27 do standardu Unicode: Unicode 3.1 (2001)
- Standard Unicode, wersja 5.0 (2006)
- Standard Unicode, wersja 6.0 (2010)
Wszystkie są takie same pod względem ogólnej mechaniki, a główne różnice dotyczą takich kwestii, jak dozwolony zakres wartości punktów kodowych i bezpieczna obsługa nieprawidłowych danych wejściowych.
Porównanie z innymi kodowaniami
Niektóre z ważnych cech tego kodowania są następujące:
- Kompatybilność wsteczna: Kompatybilność wsteczna z ASCII i ogromna ilość oprogramowania zaprojektowanego do przetwarzania tekstu zakodowanego w ASCII była główną siłą napędową projektu UTF-8. W UTF-8 pojedyncze bajty o wartościach z zakresu od 0 do 127 odwzorowują bezpośrednio punkty kodowe Unicode w zakresie ASCII. Pojedyncze bajty w tym zakresie reprezentują znaki, tak jak w ASCII. Co więcej, 7-bitowe bajty (bajty, w których najbardziej znaczącym bitem jest 0) nigdy nie pojawiają się w sekwencji wielobajtowej i żadna prawidłowa sekwencja wielobajtowa nie jest dekodowana do punktu kodowego ASCII. Sekwencja 7-bitowych bajtów jest zarówno prawidłowym kodem ASCII, jak i prawidłowym UTF-8, iw dowolnej interpretacji reprezentuje tę samą sekwencję znaków. Dlatego 7-bitowe bajty w strumieniu UTF-8 reprezentują wszystkie i tylko znaki ASCII w strumieniu. Dlatego wiele procesorów tekstu, parserów, protokołów, formatów plików, programów do wyświetlania tekstu itp., które używają znaków ASCII do celów formatowania i kontroli, będzie nadal działać zgodnie z przeznaczeniem, traktując strumień bajtów UTF-8 jako sekwencję pojedynczych znaków bajtowych, bez dekodowania sekwencji wielobajtowych. Znaki ASCII, na których obraca się przetwarzanie, takie jak znaki interpunkcyjne, spacje i znaki kontrolne, nigdy nie będą kodowane jako sekwencje wielobajtowe. Dlatego takie procesory mogą po prostu ignorować lub przepuszczać sekwencje wielobajtowe bez ich dekodowania. Na przykład można użyć białych znaków ASCII tokenizować strumień UTF-8 na słowa; Do dzielenia strumienia UTF-8 na linie można użyć przesunięć wiersza ASCII; a znaki ASCII NUL mogą być używane do dzielenia danych zakodowanych w UTF-8 na łańcuchy zakończone znakiem null. Podobnie, wiele ciągów formatujących używanych przez funkcje biblioteczne, takie jak „printf”, będzie poprawnie obsługiwać argumenty wejściowe zakodowane w UTF-8.
- Awaryjne i automatyczne wykrywanie: tylko mały podzbiór możliwych ciągów bajtów jest prawidłowym ciągiem UTF-8: kilka bajtów nie może się pojawić; bajt z ustawionym wysokim bitem nie może być sam; a dalsze wymagania oznaczają, że jest bardzo mało prawdopodobne, aby czytelny tekst w jakimkolwiek rozszerzonym ASCII był poprawnym UTF-8. Część popularności UTF-8 wynika z tego, że zapewnia on również dla nich formę kompatybilności wstecznej. Procesor UTF-8, który błędnie otrzymuje rozszerzony kod ASCII jako dane wejściowe, może zatem „automatycznie wykryć” to z bardzo dużą niezawodnością. Strumień UTF-8 może po prostu zawierać błędy, w wyniku czego schemat automatycznego wykrywania generuje fałszywe alarmy; ale automatyczne wykrywanie jest skuteczne w zdecydowanej większości przypadków, zwłaszcza w przypadku dłuższych tekstów, i jest szeroko stosowane. Działa również w celu „powrotu” lub zastąpienia 8-bitowych bajtów przy użyciu odpowiedniego punktu kodowego dla starszego kodowania w przypadku wykrycia błędów w UTF-8, umożliwiając odzyskiwanie, nawet jeśli UTF-8 i starsze kodowanie są połączone w tym samym pliku .
- Kod prefiksu : Pierwszy bajt wskazuje liczbę bajtów w sekwencji. Odczyt ze strumienia może natychmiast zdekodować każdą w pełni odebraną sekwencję, bez konieczności uprzedniego oczekiwania na pierwszy bajt następnej sekwencji lub wskazanie końca strumienia. Długość sekwencji wielobajtowych jest łatwo określana przez ludzi, ponieważ jest to po prostu liczba jedynek wyższego rzędu w bajcie wiodącym. Nieprawidłowy znak nie zostanie zdekodowany, jeśli strumień zakończy się w połowie sekwencji.
- 0 Samosynchronizacja : bajty wiodące i bajty kontynuacji nie mają wspólnych wartości (bajty kontynuacji zaczynają się od bitów 10 , podczas gdy pojedyncze bajty zaczynają się od , a dłuższe bajty wiodące zaczynają się od 11 ). Oznacza to, że wyszukiwanie nie spowoduje przypadkowego znalezienia sekwencji dla jednego znaku zaczynającego się w środku innego znaku. Oznacza to również, że początek znaku można znaleźć z losowej pozycji, wykonując kopię zapasową maksymalnie 3 bajtów, aby znaleźć wiodący bajt. Nieprawidłowy znak nie zostanie zdekodowany, jeśli strumień rozpocznie się w połowie sekwencji, a krótsza sekwencja nigdy nie pojawi się w dłuższej sekwencji.
- Kolejność sortowania: Wybrane wartości początkowych bajtów oznaczają, że listę ciągów znaków UTF-8 można posortować w kolejności punktów kodowych, sortując odpowiednie sekwencje bajtów.
Jednobajtowe
- UTF-8 może zakodować dowolny znak Unicode , unikając konieczności wymyślania i ustawiania „ strony kodowej ” lub innego wskazywania, jaki zestaw znaków jest używany, i umożliwiając wyjście w wielu skryptach jednocześnie. W przypadku wielu skryptów używano więcej niż jednego kodowania jednobajtowego, więc nawet znajomość skryptu nie zawierała wystarczających informacji, aby wyświetlić go poprawnie.
- znacznika kolejności bajtów UTF-16 i dlatego nie można go z nim pomylić. Brak 0xFF (0377) eliminuje również potrzebę ucieczki tego bajtu w Telnecie (i połączeniu sterującym FTP).
- Tekst zakodowany w UTF-8 jest większy niż wyspecjalizowane kodowanie jednobajtowe, z wyjątkiem zwykłych znaków ASCII. W przypadku skryptów, które używały 8-bitowych zestawów znaków ze znakami spoza alfabetu łacińskiego zakodowanymi w górnej połowie (takich jak większość cyrylicy i alfabetu greckiego ), znaki w UTF-8 będą dwukrotnie większe. W przypadku niektórych skryptów, takich jak tajski i dewanagari (który jest używany w różnych językach południowoazjatyckich), znaki potroją się. Istnieją nawet przykłady, w których pojedynczy bajt zamienia się w znak złożony w Unicode, a zatem jest sześciokrotnie większy w UTF-8. Wywołało to sprzeciw w Indiach i innych krajach.
- W UTF-8 (lub jakimkolwiek innym kodowaniu wielobajtowym) możliwe jest podzielenie lub obcięcie łańcucha w środku znaku. Jeśli te dwa elementy nie zostaną ponownie dodane później przed interpretacją jako znaki, może to wprowadzić nieprawidłową sekwencję zarówno na końcu poprzedniej sekcji, jak i na początku następnej, a niektóre dekodery nie zachowają tych bajtów i spowodują utratę danych. Ponieważ UTF-8 jest samosynchronizujący się, nigdy jednak nie wprowadzi innego prawidłowego znaku, a także dość łatwo jest przesunąć punkt obcięcia wstecz na początek znaku.
- Jeśli wszystkie punkty kodowe mają ten sam rozmiar, pomiary ustalonej ich liczby są łatwe. Ze względu na dokumentację ery ASCII, w której „znak” jest używany jako synonim „bajtu”, jest to często uważane za ważne. Jednak mierząc pozycje łańcuchów przy użyciu bajtów zamiast „znaków”, większość algorytmów można łatwo i skutecznie dostosować do UTF-8. Wyszukiwanie łańcucha w długim łańcuchu może być na przykład wykonywane bajt po bajcie; właściwość samosynchronizacji zapobiega fałszywym alarmom.
Inne wielobajtowe
- UTF-8 może kodować dowolny znak Unicode . Pliki w różnych skryptach mogą być poprawnie wyświetlane bez konieczności wybierania prawidłowej strony kodowej lub czcionki. Na przykład chiński i arabski można zapisać w tym samym pliku bez specjalnych znaczników lub ręcznych ustawień określających kodowanie.
- UTF-8 jest samosynchronizujący się : granice znaków można łatwo zidentyfikować, skanując w poszukiwaniu dobrze zdefiniowanych wzorców bitowych w dowolnym kierunku. Jeśli bajty zostaną utracone z powodu błędu lub uszkodzenia , zawsze można znaleźć następny prawidłowy znak i wznowić przetwarzanie. Jeśli istnieje potrzeba skrócenia łańcucha, aby pasował do określonego pola, można łatwo znaleźć poprzedni ważny znak. Wiele kodowań wielobajtowych, takich jak Shift JIS, jest znacznie trudniejszych do ponownego zsynchronizowania. Oznacza to również, że zorientowane na bajty algorytmy wyszukiwania ciągów znaków może być używany z UTF-8 (ponieważ znak jest tym samym, co „słowo” złożone z tylu bajtów), zoptymalizowane wersje wyszukiwania bajtów mogą być znacznie szybsze dzięki obsłudze sprzętowej i tabelom wyszukiwania, które mają tylko 256 wpisów. Samosynchronizacja wymaga jednak zarezerwowania bitów dla tych znaczników w każdym bajcie, co zwiększa rozmiar.
- Wydajne kodowanie za pomocą prostych operacji bitowych . UTF-8 nie wymaga wolniejszych operacji matematycznych, takich jak mnożenie lub dzielenie (w przeciwieństwie do Shift JIS , GB 2312 i innych).
- UTF-8 zajmie więcej miejsca niż kodowanie wielobajtowe zaprojektowane dla określonego skryptu. Starsze kodowania wschodnioazjatyckie zwykle używały dwóch bajtów na znak, ale zajmują trzy bajty na znak w UTF-8.
UTF-16
- Kodowanie bajtowe i UTF-8 są reprezentowane przez tablice bajtowe w programach i często nic nie trzeba robić z funkcją podczas konwersji kodu źródłowego z kodowania bajtowego na UTF-8. UTF-16 jest reprezentowany przez 16-bitowe tablice słów, a konwersja do UTF-16 przy zachowaniu zgodności z istniejącymi programami opartymi na ASCII (takimi jak miało to miejsce w systemie Windows) wymaga każdego interfejsu API i struktury danych, które wymagają powielenia łańcucha, jednego wersja akceptująca ciągi bajtów i inna wersja akceptująca UTF-16. Jeśli kompatybilność wsteczna nie jest potrzebna, cała obsługa łańcuchów nadal musi zostać zmodyfikowana.
- Tekst zakodowany w UTF-8 będzie mniejszy niż ten sam tekst zakodowany w UTF-16, jeśli jest więcej punktów kodowych poniżej U+0080 niż w zakresie U+0800..U+FFFF. Dotyczy to wszystkich współczesnych języków europejskich. Często jest to prawdą nawet w przypadku języków takich jak chiński, ze względu na dużą liczbę spacji, znaków nowej linii, cyfr i znaczników HTML w typowych plikach.
- Większość komunikacji (np. HTML i IP) oraz pamięci masowej (np. dla systemu Unix) została zaprojektowana dla strumienia bajtów . Ciąg UTF-16 musi zawierać parę bajtów dla każdej jednostki kodu:
- Kolejność tych dwóch bajtów staje się problemem i musi być określona w protokole UTF-16, na przykład za pomocą znacznika kolejności bajtów .
- Jeśli w UTF-16 brakuje nieparzystej liczby bajtów, cała reszta łańcucha będzie bezsensownym tekstem. Wszelkie brakujące bajty w UTF-8 nadal pozwolą na dokładne odzyskanie tekstu, zaczynając od następnego znaku po brakujących bajtach.
Pochodne
Poniższe implementacje wykazują niewielkie różnice w stosunku do specyfikacji UTF-8. Są one niezgodne ze specyfikacją UTF-8 i mogą zostać odrzucone przez aplikacje zgodne z UTF-8.
CESU-8
Raport techniczny Unicode nr 26 przypisuje nazwę CESU-8 niestandardowemu wariantowi UTF-8, w którym znaki Unicode w dodatkowych płaszczyznach są kodowane przy użyciu sześciu bajtów zamiast czterech bajtów wymaganych przez UTF-8. Kodowanie CESU-8 traktuje każdą połowę czterobajtowej pary zastępczej UTF-16 jako dwubajtowy znak UCS-2, dając dwa trzybajtowe znaki UTF-8, które razem reprezentują oryginalny znak dodatkowy. Znaki Unicode w ramach podstawowej płaszczyzny wielojęzycznej pojawiają się tak, jak normalnie w UTF-8. Raport został napisany w celu potwierdzenia i sformalizowania istnienia danych zakodowanych jako CESU-8, pomimo Unicode Consortium zniechęca do jego używania i zauważa, że możliwym celowym powodem kodowania CESU-8 jest zachowanie sortowania binarnego UTF-16.
Kodowanie CESU-8 może wynikać z konwersji danych UTF-16 ze znakami dodatkowymi na UTF-8 przy użyciu metod konwersji, które zakładają dane UCS-2, co oznacza, że nie są one świadome czterobajtowych znaków dodatkowych UTF-16. Jest to przede wszystkim problem w systemach operacyjnych, które intensywnie używają wewnętrznie kodowania UTF-16, takich jak Microsoft Windows . [ potrzebne źródło ]
W Oracle Database zestaw znaków UTF8 wykorzystuje kodowanie CESU-8 i jest przestarzały .
Zestaw znaków AL32UTF8
wykorzystuje zgodne ze standardami kodowanie UTF-8 i jest preferowany.
CESU-8 jest zabronione w dokumentach HTML5 .
MySQL utf8mb3
W MySQL zestaw znaków utf8mb3
jest zdefiniowany jako dane zakodowane w UTF-8 z maksymalnie trzema bajtami na znak, co oznacza, że obsługiwane są tylko znaki Unicode w Basic Multilingual Plane (tj. z UCS-2 ). Znaki Unicode w dodatkowych płaszczyznach nie są wyraźnie obsługiwane. utf8mb3
jest przestarzały na rzecz zestawu znaków utf8mb4
, który wykorzystuje zgodne ze standardami kodowanie UTF-8. utf8
jest aliasem dla utf8mb3
, ale ma stać się aliasem dla utf8mb4
w przyszłej wersji MySQL. Możliwe jest, choć nieobsługiwane, przechowywanie danych zakodowanych w CESU-8 w utf8mb3
, poprzez obsługę danych UTF-16 z dodatkowymi znakami, tak jakby to był UCS-2.
Zmodyfikowany kod UTF-8
Zmodyfikowany kod UTF-8 (MUTF-8) wywodzi się z języka programowania Java . W zmodyfikowanym UTF-8 znak null (U+0000) używa dwubajtowego kodowania overlong 110 00000 10 000000 (szesnastkowo C0 80 ), zamiast 00000000 (szesnastkowo 00 ). Zmodyfikowane ciągi UTF-8 nigdy nie zawierają żadnych rzeczywistych bajtów zerowych, ale mogą zawierać wszystkie punkty kodowe Unicode, w tym U + 0000, co pozwala na przetwarzanie takich ciągów (z dołączonym bajtem zerowym) przez tradycyjny ciąg zakończony znakiem zerowym Funkcje. Wszystkie znane zmodyfikowane implementacje UTF-8 również traktują pary zastępcze jak w CESU-8 .
W normalnym użytkowaniu język obsługuje standard UTF-8 podczas odczytywania i zapisywania ciągów znaków przez InputStreamReader
i OutputStreamWriter
(jeśli jest to domyślny zestaw znaków platformy lub zgodnie z żądaniem programu). Jednak używa zmodyfikowanego UTF-8 do serializacji obiektów między innymi aplikacjami DataInput
i DataOutput
, dla Java Native Interface oraz do osadzania stałych łańcuchów w plikach klas .
Format dex zdefiniowany przez Dalvik również używa tego samego zmodyfikowanego UTF-8 do reprezentowania wartości łańcuchowych. Tcl używa również tego samego zmodyfikowanego UTF-8 co Java do wewnętrznej reprezentacji danych Unicode, ale używa ścisłego CESU-8 do danych zewnętrznych.
WTF-8
W WTF-8 (Wobbly Transformation Format, 8-bit) dozwolone są niesparowane zastępcze połówki (od U+D800 do U+DFFF). Jest to konieczne do przechowywania prawdopodobnie nieprawidłowego kodowania UTF-16, takiego jak nazwy plików systemu Windows. Wiele systemów obsługujących UTF-8 działa w ten sposób, nie uznając tego za inne kodowanie, ponieważ jest to prostsze.
Termin „WTF-8” był również używany humorystycznie w odniesieniu do błędnie podwójnie zakodowanego UTF-8, czasami z sugestią, że bajty CP1252 są jedynymi zakodowanymi.
PEP 383
Wersja 3 języka programowania Python traktuje każdy bajt nieprawidłowego strumienia bajtów UTF-8 jako błąd (zobacz także zmiany w nowym trybie UTF-8 w Pythonie 3.7); daje to 128 różnych możliwych błędów. Rozszerzenia zostały stworzone, aby umożliwić bezstratną transformację dowolnej sekwencji bajtów, która ma być UTF-8, do UTF-16 lub UTF-32, poprzez przetłumaczenie 128 możliwych bajtów błędów na zarezerwowane punkty kodowe i przekształcenie tych punktów kodowych z powrotem w błąd bajtów do wyprowadzenia UTF-8. Najczęstszym podejściem jest przetłumaczenie kodów na U+DC80...U+DCFF, które są niskimi (końcowymi) wartościami zastępczymi, a zatem „nieprawidłowymi” UTF-16, używanymi przez Pythona podejście PEP 383 (lub „zastępcza ucieczka”). Inne kodowanie o nazwie MirBSD OPTU-8/16 konwertuje je na U+EF80...U+EFFF w obszarze użytku prywatnego . W obu podejściach wartość bajtu jest kodowana w ośmiu niższych bitach wyjściowego punktu kodowego.
Te kodowania są bardzo przydatne, ponieważ pozwalają uniknąć konieczności zajmowania się „nieprawidłowymi” ciągami bajtów do znacznie późniejszego czasu, jeśli w ogóle, i pozwalają tablicom bajtów „tekst” i „dane” być tym samym obiektem. Jeśli program chce używać wewnętrznie UTF-16, musi zachować i używać nazw plików, które mogą używać nieprawidłowego UTF-8; ponieważ interfejs API systemu plików Windows używa UTF-16, potrzeba obsługi nieprawidłowego UTF-8 jest tam mniejsza.
Aby kodowanie było odwracalne, standardowe kodowanie UTF-8 punktów kodowych używanych dla błędnych bajtów musi zostać uznane za nieprawidłowe. To sprawia, że kodowanie jest niezgodne z WTF-8 lub CESU-8 (choć tylko dla 128 punktów kodowych). Podczas ponownego kodowania należy uważać na sekwencje punktów kodu błędów, które konwertują z powrotem do prawidłowego UTF-8, co może być wykorzystane przez złośliwe oprogramowanie do uzyskania nieoczekiwanych znaków na wyjściu, chociaż nie może to generować znaków ASCII, dlatego uważa się, że stosunkowo bezpieczne, ponieważ złośliwe sekwencje (takie jak cross-site scripting ) zwykle opierają się na znakach ASCII.
Zobacz też
- Kod alternatywny
- Porównanie klientów pocztowych § Funkcje
-
Porównanie kodowań Unicode
- GB 18030 , chińskie kodowanie, choć w pełni obsługuje Unicode
- UTF-EBCDIC , rzadko używane kodowanie, nawet dla komputerów mainframe , dla których zostało stworzone
- Ikonav
- Kodowanie procentowe § Obecny standard
- Specjalne (blok Unicode)
- Unicode i e-mail
- Unicode i HTML w HTML
Notatki
Linki zewnętrzne
- Oryginalny papier UTF-8 ( lub pdf ) dla Planu 9 z Bell Labs
- Historia UTF-8 autorstwa Roba Pike'a
- Strony testowe UTF-8:
- Unix/Linux: UTF-8/Unicode FAQ , Linux Unicode HOWTO , UTF-8 i Gentoo
- na YouTubie