úterý 26. srpna 2003

UTF-8 : Problém "malého a velkého indiána"

Ten "malý a velký indián" je ve skutečnosti big a little endian a s partou rudochů kolem Vinnetou nemá co dočinění. V blogu IVTLog dj Padák objevil problém se znakovým kódováním UTF-8. Jedná se o efekt, kdy se ve výsledné stránce zobrazí čtvereček viz. obrázek a dj Padák o něm píše

Pokud v PHP skládáte výslednou stránku pomocí příkazů include nebo require, zobrazí se takový podivný znak na místě začátku každého vloženého souboru. Zajímalo by mě, kde je problém?

Problém je způsoben textovými editory, které na začátek souboru připojí řídící znaky \u010F\u00BB\u017E. Tyto znaky se nazývají ByteOrderMagic (BOM) a jejich úlohou je specifikovat, jestli jsou znaky, lépe řečeno jejich bytová reprezentace uložena ve "formátu" big endian nebo little endian.

Význam řídících znaků

Proto abychom mohli pochopit význam "malého a velkého indiána" si musíme uvědomit, že v kódování UTF-8 se znaky pro které nestačí jeden byte kódují dvěma byty. V takovém případě je třeba rozlišit jestli byte s vyšším řádem bude uložen v této dvojici jako první nebo jako druhý. Pokud je použit Big endian je byte s vyšším řádem uložen jako první, u little endianu je to samozřejmě naopak.

Znak jehož hexadecimální hodnota by odpovídala 0x00FF, by byll při big endian uložen v pořadí

  • byte s větším řádem, tedy 00
  • byte s menším řádem, tedy FF

Právě pořadí bytů je důležité při dalším zpracování, ovšem na výstupu by měl být řídící znaku určující big nebo little endian potlačeny a měly by sloužit pouze k interní potřebě. Některé editory nebo koncové programy tyto řídící znaky interpretují na výstup, což je i případ PHP což je patrné na obrázku. Stejný problém byl i v Jave (JDK 1.3), v novějších verzích je to odstraněno.

Řešení se nabízí v podobě odmazání těchto řídících znaků a uložení souboru. Já osobně to řeším například ve vývojové platformě Eclipse, kterou používám. Zobrazení těchto znaku určitě zvládnou i jiné editory. Tímto malým hackem si ovšem zaděláme na problém, pokud narazíme na program který bude implicitně předpokládat opačného "indiána" než jsme použili.

11.09.2003 další doplňující informace k problematice BOM v UTF-8