Metaproblem ke konferenci samotne

Michal Kubecek mike na mk-sys.cz
Úterý Srpen 31 09:57:54 CEST 2004


On Tue, Aug 31, 2004 at 03:49:46AM +0200, Petr Vileta wrote:
> >
> >   1. Text v UTF-16 je obvykle delší než v UTF-8
> Ja to nijak nezkoumal, ale mel jsem za to, ze UTF16 je vzdycky
> dvoubajtovy.

To byste s UTF-16 nebyl schopen pokrýt celý rozsah Unicode, jehož
prostor je definován jako 32-bitový. Prakticky sice jsou sice všechny
znaky, se kterými se běžně setkáte (možná i všechny zatím deklarované)
zapsány dvěma byty, ale teoreticky to může být až šest. Podstatné je, že
chcete-li opravdu korektně implementovat UTF-16, musíte stejně počítat
s proměnnou délkou znaku, stejně jako u UTF-8. Z praktického hlediska
jsou ale běžné texty v UTF-16 delší, protože znaky z rozsahu 0x00-0x7F
zapíšete v UTF-8 jedním bytem, ale v UTF-16. Existují sice i znaky, na
které potřebujete 3 byty v UTF-8 a 2 v UTF-16, ale jejich frekvence
v českých textech (i ostatních evropských jazycích) je řádově nižší.

> >   2. U textu v UTF-16 musíte, na rozdíl od UTF-8, řešit endianness
> Co jsou to ty Indianes? :-)

Ukládáte-li do paměti vícebytovou hodnotu, máte dva způsoby, jak to
udělat. Např. pro číslo 260 = 0x0104 to bude

  (a) 04 01 ... little endian, LSB first
  (b) 01 04 ... big endian, MSB first

Analogicky to funguje i pro delší, např. 32-bitová čísla. Dokud
pracujete na jedné platformě, je to jedno, ale jakmile data vyměňujete
mezi platformami, musíte se na jedné variantě dohodnout. Protože UTF-8
používá jako základní jednotku osmibitový blok (byte), tento problém u
něj nevzniká. U UTF-16 ale pracujete s 16-bitovými bloky, takže máte
vlastně dvě různá kódování UTF-16LE a UTF-16BE. Buď musíte explicitně
specifikovat, kterou variantu používáte, nebo můžete použít trik, který
se u UTF-16 ujal: na začátek souboru přidat značku, podle níž se to
pozná. Pro tyto účely se používá znak "zero width non-breakable space",
který má tu zvláštnost, že při prohození pořadí bytů dostanete znak,
který neexistuje a je garantováno, že ani nikdy existovat nebude. Proto
se mu také někdy říká BOM (byte ordering mark). Problém ale je, že
editor nebo jiný program a priori neví, jestli to je normální znak, nebo
jen značka pro rozlišení BE/LE, takže třeba při spojení dvou souborů
(např. include/require v PHP) vám pak najednou vyleze tento podivný
znak. U obyčejných textů to příliš nevadí, mezera nulové šířky je
"neviditelná", ale u programovacího jazyka to obvykle znamená
syntaktickou chybu.

Na druhou stranu nevím o žádném důvodu, proč by UTF-16 bylo v principu
lepší než UTF-8. Praktickým důvodem může být samozřejmě to, že ve
Windows se dává přednost UTF-16 - nejsem si ale jistý, jestli to
fakticky není spíš UCS-2, tj. kódování, které používá vždy právě dva
byty na znak, ale obsáhne pouze rozsah od U+0000 do U+FFFF.

							  Michal Kubeček



Další informace o konferenci Linux