encyklopedia.space

UTF‑16

UTF‑16 (ang. Unicode Transformation Format – 16‑bit) jest jedną z trzech najpopularniejszych metod kodowania znaków w standardzie Unicode. Stosuje się go do reprezentacji kodowania znaków w postaci 16‑bitowych jednostek kodowych (słówek), które mogą być jedną lub dwiema takimi jednostkami, w zależności od położenia znaku w przestrzeni kodowej Unicode.

Historia

Uzasadnieniem wprowadzenia UTF‑16 była potrzeba zapewnienia jednolitego i wydajnego kodowania dla języków wymagających ponad 8 bitów na znak, ale jednocześnie zachowanie względnej kompatybilności z istniejącymi systemami 16‑bitowymi. Standard ten został opisany po raz pierwszy w Unicode 2.0 (1996) i od tego czasu stał się domyślnym formatem wewnętrznym w wielu językach programowania, m.in. w Java i .NET.

Budowa i zasada działania

W UTF‑16 każdy znak Unicode jest reprezentowany za pomocą jednej lub dwóch 16‑bitowych jednostek kodowych:

  • Znaki znajdujące się w BMP (Basic Multilingual Plane, zakres U+0000–U+FFFF) są kodowane jednym słowem 16‑bitowym.
  • Znaki spoza BMP (U+10000–U+10FFFF) są kodowane przy pomocy par surogatów. Pierwszy słówko (wysoki surogat) mieści się w przedziale D800–DBFF, a drugi (niski surogat) w przedziale DC00–DFFF.

Porządek bajtowy (endianness)

UTF‑16 jest formatem endianness‑zależnym. Aby umożliwić poprawne odczytanie strumienia bajtów, na początku pliku (lub strumienia) może znajdować się znak BOM (Byte Order Mark) o wartości U+FEFF, który wskazuje kolejność bajtów:

  • FE FF – kolejność big‑endian (MSB najpierw).
  • FF FE – kolejność little‑endian (LSB najpierw).

Zastosowania

UTF‑16 jest wykorzystywany w wielu technologiach i systemach:

  • Język programowania Java używa UTF‑16 jako wewnętrznego formatu przechowywania char.
  • Platforma .NET definiuje typ System.String jako sekwencję 16‑bitowych kodów UTF‑16.
  • System operacyjny Windows w niektórych interfejsach API (np. W‑wersje funkcji) przyjmuje i zwraca łańcuchy w UTF‑16.
  • Formaty plików multimedialnych i dokumentów, takie jak HTML5 (w atrybucie charset="utf-16"), XML, JSON (przy odpowiedniej deklaracji), korzystają z UTF‑16.

Porównanie z innymi kodowaniami Unicode

Kodowanie Rozmiar jednostki Zakres BMP Obsługa znaków poza BMP Zastosowania typowe
UTF‑8 1‑4 bajty 1 bajt (ASCII) – 3 bajty 4 bajty (sekwencja) Internet, pliki tekstowe, systemy Unix‑like
UTF‑16 2 lub 4 bajty (jedno lub dwa słowa 16‑bitowe) 2 bajty 4 bajty (para surogatów) Java, .NET, Windows API
UTF‑32 4 bajty 4 bajty 4 bajty Systemy wymagające stałej długości kodu

Implementacje i wsparcie w bibliotekach

Większość współczesnych języków programowania i bibliotek standardowych udostępnia funkcje konwersji między UTF‑16 a innymi formatami:

  • W C++ biblioteka <codecvt> (od C++11) obsługuje konwersję UTF‑16.
  • W Pythonie typ str jest wewnętrznie kodowany w UTF‑16 na platformach Windows i UTF‑32 na innych.
  • W JavaScript ciągi znaków są reprezentowane jako sekwencja 16‑bitowych kod jednostek, co wymaga specjalnych metod (np. codePointAt) przy obsłudze znaków spoza BMP.

Problemy i ograniczenia

Choć UTF‑16 jest wydajny dla języków, które używają głównie znaków BMP (np. większość języków europejskich i azjatyckich), posiada kilka istotnych wad:

  • Rozmiar pamięci nie jest stały – znak spoza BMP zajmuje podwójną ilość pamięci.
  • Potrzeba obsługi par surogatów wprowadza dodatkową złożoność przy operacjach na ciągach (np. liczenie znaków, indeksowanie).
  • W zależności od endianness może być konieczne użycie BOM, co nie jest wymagane w UTF‑8 i może powodować problemy przy niewłaściwym rozpoznawaniu kolejności bajtów.

Przykłady kodowania

Poniżej przedstawiono kilka przykładów kodowania wybranych znaków w UTF‑16 (big‑endian, bez BOM):

Znak U+ kod punktowy UTF‑16 (hex) Opis
A U+0041 00 41 Łaciński wielki znak A
Ω U+03A9 03 A9 Grecka wielka litera omega
𐍈 U+10348 D8 00 DF 48 Runiczny znak „ha” (poza BMP, para surogatów)

Patrz także