UTF -16 - UTF-16

UTF-16
Unifont Full Map.png
Prvních 2 16 bodů kódu Unicode. Proužek plné šedé v dolní části jsou náhradní poloviny používané UTF-16 (bílá oblast pod pruhem je oblast soukromého použití )
Jazyk (y) Mezinárodní
Standard Standard Unicode
Klasifikace Transformační formát Unicode , kódování s proměnnou šířkou
Rozšiřuje UCS-2
Transformuje / kóduje ISO 10646 ( Unicode )

UTF-16 ( 16bitový formát transformace Unicode ) je kódování znaků schopné kódovat všech 1 112 064 platných bodů kódu znaku Unicode (ve skutečnosti je tento počet bodů kódu určen designem UTF-16). Kódování má proměnnou délku , protože kódové body jsou kódovány jednou nebo dvěma 16bitovými kódovými jednotkami . UTF-16 vznikl z dřívějšího zastaralého 16bitového kódování s pevnou šířkou, nyní známého jako UCS-2 (pro 2bajtovou univerzální znakovou sadu), jakmile vyšlo najevo, že je potřeba více než 2 16 (65 536) kódových bodů.

UTF-16 interně používají systémy jako Microsoft Windows , programovací jazyk Java a JavaScript /ECMAScript. Často se také používá pro prostý text a pro datové soubory pro zpracování textu v systému Microsoft Windows. Málokdy se používá pro soubory v unixových systémech. V květnu 2019 Microsoft obrátil svůj směr pouze s důrazem na UTF-16 pro Unicode; pro aplikace pro Windows společnost Microsoft doporučuje a podporuje UTF-8 (např. pro aplikace Universal Windows Platform (UWP).).

UTF-16 je jediné webové kódování nekompatibilní s ASCII a nikdy nezískalo popularitu na webu, kde ho používá méně než 0,002% (něco přes 1 tisícinu z 1 procenta) webových stránek. Pro srovnání, UTF-8 používá 97% všech webových stránek. Hypertext Application Technology Working Group Web (WHATWG) se domnívá, UTF-8 "povinné kódování pro všechny [text]" a že z bezpečnostních důvodů by se aplikace prohlížeče nepoužívá UTF-16.

Dějiny

Na konci osmdesátých let začaly práce na vývoji jednotného kódování pro „univerzální znakovou sadu“ ( UCS ), které by nahradilo dřívější jazykově specifická kódování jedním koordinovaným systémem. Cílem bylo zahrnout všechny požadované znaky z většiny světových jazyků a také symboly z technických oblastí, jako je věda, matematika a hudba. Původní myšlenka byla nahradit typická kódování 256 znaků, která vyžadovala 1 bajt na znak, kódováním s použitím 65 536 (2 16 ) hodnot, což by vyžadovalo 2 bajty (16 bitů) na znak.

Souběžně na tom pracovaly dvě skupiny, ISO/IEC JTC 1/SC 2 a Unicode Consortium , přičemž druhá skupina zastupovala převážně výrobce výpočetního zařízení. Obě skupiny se pokusily synchronizovat svá přiřazení znaků tak, aby vyvíjející se kódování bylo vzájemně kompatibilní. Počáteční 2bajtové kódování se původně nazývalo „Unicode“, ale nyní se nazývá „UCS-2“.

Když bylo stále jasnější, že 2 16 znaků nebude stačit, zavedl IEEE větší 31bitový prostor a kódování ( UCS-4 ), které by vyžadovalo 4 bajty na znak. Tomu odolalo konsorcium Unicode , a to jednak proto, že 4 bajty na znak plýtvaly spoustou paměti a místa na disku, a jednak proto, že někteří výrobci již byli výrazně investováni do technologie 2 bajty na znak. Schéma kódování UTF-16 bylo vyvinuto jako kompromis a zavedeno ve verzi 2.0 standardu Unicode v červenci 1996. Je plně specifikováno v RFC 2781, publikovaném v roce 2000 IETF .

V kódování UTF-16, body kódu méně než 2 16 jsou kódovány s jedním 16-bitový kód jednotky rovná číselné hodnoty v kódu, jak je ve starších UCS-2. Novější kódové body větší nebo rovné 2 16 jsou kódovány složenou hodnotou pomocí dvou 16bitových kódových jednotek. Tyto dvě 16bitové kódové jednotky jsou vybrány z náhradního rozsahu UTF-16 0xD800–0xDFFF, který nebyl dříve přiřazen znakům. Hodnoty v tomto rozsahu nejsou použity jako znaky a UTF-16 neposkytuje žádný legální způsob, jak je kódovat jako jednotlivé body kódu. Tok UTF-16 se tedy skládá z jednotlivých 16bitových kódových bodů mimo náhradní rozsah pro kódové body v základní vícejazyčné rovině (BMP) a párů 16bitových hodnot v náhradním rozsahu pro kódové body nad BMP.

UTF-16 je specifikován v nejnovějších verzích mezinárodní normy ISO/IEC 10646 a Unicode Standard. "UCS-2 by nyní měl být považován za zastaralý. Už se nevztahuje na kódovací formu v 10646 ani v Unicode Standard." Od roku 2021 neexistují žádné plány na rozšíření UTF-16 na podporu většího počtu kódových bodů nebo kódových bodů nahrazených náhradními, protože by to porušilo zásady stability Unicode ohledně obecné kategorie nebo náhradních kódových bodů. (Každé schéma, které zůstane samosynchronizačním kódem, by pro zahájení sekvence vyžadovalo přidělení alespoň jednoho bodu kódu BMP. Změna účelu bodu kódu není povolena.)

Popis

Každý bod kódu Unicode je kódován buď jako jedna nebo dvě 16bitové kódové jednotky . Jak jsou tyto 16bitové kódy uloženy jako bajty, pak závisí na „ endianness “ textového souboru nebo komunikačního protokolu.

Nahrávání „znaku“ může vyžadovat od pouhých dvou bytů po čtrnáct nebo dokonce více bytů. Například znak příznaku emoji má 8 bytů, protože je „vytvořen z dvojice skalárních hodnot Unicode“ (a tyto hodnoty jsou mimo BMP a vyžadují 4 bajty).

U+0000 až U+D7FF a U+E000 až U+FFFF

UTF-16 i UCS-2 kódují kódové body v tomto rozsahu jako jediné 16bitové kódové jednotky, které jsou číselně stejné jako odpovídající kódové body. Tyto kódové body v základní vícejazyčné rovině (BMP) jsou jediné kódové body, které lze v UCS-2 reprezentovat. Od Unicode 9.0 některé moderní skripty mimo Latinskou Asii, Blízký východ a Afriku spadají mimo tento rozsah, stejně jako většina znaků emodži .

Kódujte body od U+010000 do U+10FFFF

Kódové body z ostatních rovin (nazývané doplňkové roviny ) jsou kódovány jako dvě 16bitové kódové jednotky nazývané náhradní pár podle následujícího schématu:

Dekodér UTF-16
Nízký
Vysoký
DC00 DC01    ...    DFFF
D800 010000 010001 ... 0103FF
D801 010400 010401 ... 0107FF
  ⋮
DBFF 10FC00 10FC01 ... 10FFFF
  • 0x10000 se odečte od bodu kódu (U) , přičemž v rozsahu hexadecimálních čísel 0x00000–0xFFFFF zůstane 20bitové číslo (U ') . Poznámka pro tyto účely je U definována tak, aby nebyla větší než 0x10FFFF.
  • Vysokých deset bitů (v rozsahu 0x000–0x3FF) se přidá k 0xD800, aby se získala první 16bitová kódová jednotka nebo vysoká náhrada (W1) , která bude v rozsahu 0xD800–0xDBFF .
  • Nízkých deset bitů (také v rozsahu 0x000–0x3FF) se přidá k 0xDC00, aby byla získána druhá 16bitová kódová jednotka nebo low surrogate (W2) , která bude v rozsahu 0xDC00–0xDFFF .

Vizuálně znázorněno, rozdělení U ' mezi W1 a W2 vypadá takto:

U' = yyyyyyyyyyxxxxxxxxxx  // U - 0x10000
W1 = 110110yyyyyyyyyy      // 0xD800 + yyyyyyyyyy
W2 = 110111xxxxxxxxxx      // 0xDC00 + xxxxxxxxxx

Vysoké náhradního a nízký náhradní jsou také známé jako „přední“ a „zadní“ náhrady, respektive, analogický s předními a zadními bytů UTF-8.

Protože rozsahy pro vysoké náhražky ( 0xD800–0xDBFF ), nízké náhrady ( 0xDC00–0xDFFF ) a platné znaky BMP (0x0000–0xD7FF, 0xE000–0xFFFF) jsou nesouvislé , není možné, aby se náhrada shodovala se znakem BMP, nebo aby dvě sousední kódové jednotky vypadaly jako legální náhradní pár . To velmi zjednodušuje vyhledávání. To také znamená, že UTF-16 se samo synchronizuje na 16bitových slovech: zda kódová jednotka začíná znakem, lze určit bez zkoumání dřívějších kódových jednotek (tj. Typ kódové jednotky lze určit rozsahy hodnot, ve kterých je pády). UTF-8 sdílí tyto výhody, ale mnoho dřívějších schémat vícebajtového kódování (například Shift JIS a jiná asijská vícebajtová kódování) neumožňovalo jednoznačné vyhledávání a bylo možné je synchronizovat pouze opětovnou analýzou od začátku řetězce (UTF -16 se nesynchronizuje, pokud dojde ke ztrátě jednoho bajtu nebo pokud přechod začíná na náhodném bajtu).

Protože nejčastěji používané znaky jsou všechny v BMP, manipulace s náhradními páry není často důkladně testována. To vede k přetrvávajícím chybám a potenciálním problémům s bezpečností, a to i v populárním a dobře recenzovaném aplikačním softwaru (např. CVE - 2008-2938 , CVE- 2012-2135 ).

Tyto Doplňkové letadla obsahují emodži , historických skriptů, méně často používané symboly, méně používané čínské ideographs atd Vzhledem k tomu, že kódování doplňkových rovin obsahuje 20 významných bitů (10 z 16 bitů v každém z vysoko a nízké náhražek ), 2 20 body kódu může být kódovány, rozděleny do 16 rovin po 2 16 kódových bodech. Včetně samostatně ovládané základní vícejazyčné roviny je celkem 17 letadel.

U+D800 až U+DFFF

Standard Unicode tyto bodové hodnoty kódu trvale rezervuje pro kódování vysokých a nízkých náhrad UTF-16 a nikdy jim nebude přiřazen znak, takže by neměl být důvod je kódovat. Oficiální standard Unicode říká, že žádné formuláře UTF, včetně UTF-16, nemohou kódovat tyto body kódu.

UCS-2, UTF-8 a UTF-32 však mohou kódovat tyto body kódu triviálními a zřejmými způsoby a velké množství softwaru to dělá, přestože standard uvádí, že s takovými uspořádáními by se mělo zacházet jako s chybami kódování.

Je možné jednoznačně zakódovat nepárový náhradní (vysoký bod náhradního kódu, za nímž nenásleduje nízký, nebo nízký, kterému nepředchází vysoký), ve formátu UTF-16 pomocí kódové jednotky rovnající se kódovému bodu . Výsledkem není platný UTF-16, ale většina implementací kodéru a dekodéru UTF-16 to dělá při překládání mezi kódováním. Windows umožňuje nepárové zástupné názvy v názvech souborů a na jiných místech, což obecně znamená, že musí být podporovány softwarem navzdory jejich vyloučení ze standardu Unicode.

Příklady

Chcete-li kódovat U+10437 (𐐷) do UTF-16:

  • Odečtěte 0x10000 od bodu kódu, ponechte 0x0437.
  • U vysokých náhrad posuňte doprava o 10 (vydělte 0x400), poté přidejte 0xD800, výsledkem je 0x0001 + 0xD800 = 0xD801.
  • Pro nízkou náhradu vezměte nízkých 10 bitů (zbytek dělení 0x400), poté přidejte 0xDC00, což má za následek 0x0037 + 0xDC00 = 0xDC37.

Dekódování U+10437 (𐐷) z UTF-16:

  • Vezměte vysokou náhradu (0xD801) a odečtěte 0xD800, poté vynásobte 0x400, výsledkem je 0x0001 × 0x400 = 0x0400.
  • Vezměte nízkou náhradu (0xDC37) a odečtěte 0xDC00, což má za následek 0x37.
  • Sečtěte tyto dva výsledky dohromady (0x0437) a nakonec přidejte 0x10000, abyste získali konečný dekódovaný kódový bod UTF-32, 0x10437.

Následující tabulka shrnuje tento převod, stejně jako další. Barvy udávají, jak jsou bity z bodu kódu rozděleny mezi bajty UTF-16. Další bity přidané procesem kódování UTF-16 jsou zobrazeny černě.

Charakter Bod binárního kódu Binární UTF-16
Jednotky hexadecimálního kódu UTF-16

Šestihranné bajty UTF-16BE

Šestihranné bajty UTF-16LE
$ U+0024 0000 0000 0010 0100 0000 0000 0010 0100 0024 00 24 24 00
U+20AC 0010 0000 1010 1100 0010 0000 1010 1100 20AC 20 AC AC 20
𐐷 U+10437 0001 0000 0100 0011 0111 1101 1000 0000 0001 1101 1100 0011 0111 D801 DC37 D8 01 DC 37 01 D8 37 DC
𤭢 U+24B62 0010 0100 1011 0110 0010 1101 1000 0101 0010 1101 1111 0110 0010 D852 DF62 D8 52 DF 62 52 D8 62 DF

Schémata kódování podle pořadí bytů

UTF-16 a UCS-2 produkují sekvenci 16bitových kódových jednotek. Protože většina komunikačních a úložných protokolů je definována pro bajty a každá jednotka tedy zabírá dva 8bitové bajty, může pořadí bajtů záviset na endianitě (pořadí bajtů) počítačové architektury.

Aby pomohl rozpoznat pořadí bajtů kódových jednotek, UTF-16 umožňuje , aby před první skutečnou kódovanou hodnotou byla značka BOM ( Byte Order Mark ), kódový bod s hodnotou U+FEFF. (U+FEFF je neviditelný znak nulové šířky bez přerušení /znak ZWNBSP.) Pokud se endianová architektura dekodéru shoduje s kodérem, dekodér detekuje hodnotu 0xFEFF, ale dekodér opačného konce interpretuje kusovník jako pro tento účel vyhrazena neznaková hodnota U+FFFE. Tento nesprávný výsledek poskytuje nápovědu k provedení výměny bajtů pro zbývající hodnoty.

Pokud kusovník chybí, RFC 2781 doporučuje, aby se předpokládalo kódování big-endian. V praxi mnoho aplikací předpokládá, že systém Windows používá ve výchozím nastavení pořadí malých endianů. Je také spolehlivé detekovat endianness hledáním nulových bajtů za předpokladu, že znaky menší než U+0100 jsou velmi běžné. Pokud je více sudých bajtů (začínajících na 0) nulových, pak je to big-endian.

Standard také umožňuje, aby bylo pořadí bajtů výslovně uvedeno zadáním UTF-16BE nebo UTF-16LE jako typu kódování. Když je pořadí bajtů výslovně specifikováno tímto způsobem, rozpiska se výslovně nepředpokládá, že by byla před text přidána, a U+FEFF na začátku by mělo být zpracováno jako znak ZWNBSP. Většina aplikací i přes toto pravidlo ignoruje kusovník ve všech případech.

Pro internetové protokoly schválila IANA jako názvy pro tato kódování „UTF-16“, „UTF-16BE“ a „UTF-16LE“ (názvy nerozlišují velká a malá písmena). Aliasy UTF_16 nebo UTF16 mohou mít v některých programovacích jazycích nebo softwarových aplikacích smysl, ale v internetových protokolech se nejedná o standardní názvy.

Podobná označení, UCS-2BE a UCS-2LE , se používají k zobrazení verzí UCS-2 .

Používání

UTF-16 se používá pro text v OS API všech aktuálně podporovaných verzí systému Microsoft Windows (a včetně alespoň všech od Windows CE / 2000 / XP / 2003 / Vista / 7 ) včetně Windows 10 . V systému Windows XP není v žádném písmu dodaném se systémem Windows pro evropské jazyky obsažen žádný bod kódu nad U+FFFF. Starší systémy Windows NT (před Windows 2000) podporují pouze UCS-2. Soubory a síťová data bývají kombinací kódování UTF-16, UTF-8 a starších bajtů.

I když byla nějaká podpora UTF-8 dokonce pro Windows XP, byla vylepšena (zejména schopnost pojmenovat soubor pomocí UTF-8) ve Windows 10 insider build 17035 a aktualizaci z dubna 2018 a od května 2019 Microsoft doporučuje software použijte místo UTF-16.

I IBM operační systém určí CCSID ( kód strana ) 13488 pro UCS-2 kódování a CCSID 1200 na UTF-16 kódování, i když systém zpracovává je oba jako UTF-16.

UTF-16 používají operační systémy Qualcomm BREW ; že .NET prostředí; a Qt multiplatformní sada grafických widgetů .

Symbian OS používaný v telefonech Nokia S60 a Sony Ericsson UIQ používá UCS-2. Sluchátka iPhone používají UTF-16 pro službu krátkých zpráv namísto UCS-2 popsaných ve standardech 3GPP TS 23.038 ( GSM ) a IS-637 ( CDMA ).

Systém souborů Joliet , používaný na médiích CD-ROM , kóduje názvy souborů pomocí UCS-2BE (až šedesát čtyři znaků Unicode na název souboru).

Python jazyk prostředí oficiálně používá pouze UCS-2 vnitřně od verze 2.0, ale v dekodéru UTF-8 na „Unicode“ vytváří správné UTF-16. Od Pythonu 2.2 jsou podporovány „široké“ verze Unicode, které místo toho používají UTF-32; ty se primárně používají na Linuxu. Python 3.3 již nikdy nepoužívá UTF-16, místo toho je zvoleno kódování, které poskytuje nejkompaktnější reprezentaci pro daný řetězec, z ASCII/Latin-1, UCS-2 a UTF-32.

Java původně používala UCS-2 a v J2SE 5.0 přidala podporu doplňkových znaků UTF-16 .

JavaScript může používat UCS-2 nebo UTF-16. Od ES2015 byly do jazyka přidány řetězcové metody a příznaky regulárních výrazů, které umožňují zpracování řetězců z hlediska agnostického kódování.

V mnoha jazycích citované řetězce potřebují novou syntaxi pro citování znaků jiných než BMP, protože "\uXXXX"syntaxe ve stylu C se výslovně omezuje na 4 hexadecimální číslice. Následující příklady ilustrují syntaxi znaku „𝄞“, který není BMP (U+1D11E, MUSICAL SYMBOL G CLEF). Nejběžnějším (používaným C ++ , C# , D a několika dalšími jazyky) je použít velká písmena „U“ s 8 hexadecimálními číslicemi, jako je "\U0001D11E". V regulárních výrazech Java 7, ICU a Perl "\x{1D11E}"je nutné použít syntaxi ; podobně v ECMAScript 2015 (JavaScript) je únikový formát "\u{1D11E}". V mnoha jiných případech (například Java mimo regulární výrazy) je jediným způsobem, jak získat znaky jiné než BMP, zadat náhradní poloviny jednotlivě, například: "\uD834\uDD1E"pro U+1D11E.

Implementace řetězců založené na UTF-16 obvykle definují délky řetězce a umožňují indexování z hlediska těchto 16bitových kódových jednotek , nikoli z hlediska kódových bodů. Ani kódové body, ani kódové jednotky neodpovídají ničemu, co by koncový uživatel mohl rozpoznat jako „znak“; věci, které uživatelé identifikují jako znaky, mohou obecně sestávat z bodu základního kódu a sekvence kombinujících znaků (nebo to může být posloupnost kódových bodů jiného druhu, například Hangul spojující jamos) - Unicode označuje tuto konstrukci jako grafém cluster  - a jako takové se aplikace zabývající se řetězci Unicode, bez ohledu na kódování, musí vyrovnat s tím, že to omezuje jejich schopnost libovolně rozdělovat a kombinovat řetězce.

UCS-2 je podporován také jazykem PHP a MySQL.

Swift , verze 5, preferovaný aplikační jazyk Apple, přešel z preferovaného kódování z UTF-16 na UTF-8.

Viz také

Poznámky

Reference

externí odkazy