Přejít k navigační liště

Zdroják » Webdesign » ISO, WIN, nebo MAC? Válka o kódování češtiny na webu

ISO, WIN, nebo MAC? Válka o kódování češtiny na webu

Kdo se webem zabýval na přelomu tisíciletí, zná ten pohled: stránka se načte a místo české věty se na ní objeví změť znaků jako ą, ľ a ». Nebyla to chyba monitoru ani písma. Byl to následek války, která se na českém internetu vedla po dlouhá léta. Šlo v ní o zdánlivou maličkost: jak do jednoho bajtu vměstnat písmeno „ř“. Podívejme se, kdo v ní proti komu stál, proč ji nešlo vyhrát a jak skončila.

Nálepky:

Doba bez háčků

Počítače vznikaly v angličtině a jejich znaková sada tomu odpovídala. Kód ASCII má sedm bitů, tedy 128 znaků: anglickou abecedu, číslice, interpunkci a řídicí znaky. Písmena „č“ nebo „ů“ v něm nenajdete. Čeští uživatelé si proto pomáhali, jak mohli. E-maily se psaly „bez hacku a carek“ a kdo chtěl diakritiku, sáhl po národních variantách sedmibitové tabulky podle normy ISO 646, v nichž se na místě některých interpunkčních znaků objevovala písmena s háčky a čárkami. Měly ale jeden háček: tytéž pozice v tabulce potřebují programovací jazyky třeba pro složené závorky, takže zdrojový kód vypadal v českém prostředí pozoruhodně.

Zlom nastal s osmibitovým bajtem. Najednou bylo k dispozici dalších 128 pozic (kódy 128 až 255) a každý je zaplnil po svém. Pro západní Evropu vznikla tabulka ISO 8859-1, známá jako Latin-1, s písmeny pro francouzštinu, němčinu nebo španělštinu. Střední Evropa ale potřebovala jiné znaky a čeština se do Latin-1 nevešla. Vznikla proto celá řada vzájemně nekompatibilních tabulek.

Bojující strany

Ještě před příchodem webu se v době MS-DOS prosadily dvě tabulky: kódová stránka CP852 (označovaná jako Latin 2) a kódování bratří Kamenických (KEYBCS2), které bylo v českých programech velmi rozšířené. Na unixových systémech se vyskytovalo také KOI8-CS. Na web ale dorazily hlavně tři tábory.

ISO 8859-2 (Latin-2) je mezinárodní norma pro střední a východní Evropu. Pokrývá češtinu, slovenštinu, polštinu, maďarštinu, chorvatštinu, slovinštinu a další jazyky psané latinkou. Používala se na unixových serverech a v internetových standardech, v HTTP hlavičce ji najdete pod názvem ISO-8859-2. Její zastánci měli silný argument: je to standard.

windows-1250 (WIN) je kódová stránka společnosti Microsoft pro střední Evropu. Žádná norma to není, ale běžela na milionech počítačů. V českých Windows se skrývala pod nepřesným označením „ANSI“. Poznámkový blok, Outlook Express i webové stránky uložené z Wordu pracovaly ve windows-1250, a autoři stránek proto často vycházeli právě z ní.

MacCE (MAC) je tabulka společnosti Apple pro starší systémy Mac OS. Macintoshe byly a jsou oblíbené mezi grafiky a v polygrafii, takže kódování MacCE se objevovalo u lidí, kteří weby navrhovali a texty pro ně připravovali.

Žádná z těchto tabulek nebyla špatná. Každá fungovala uvnitř svého světa a potíže začaly ve chvíli, kdy se světy propojily. A web je přesně k tomu určen.

Rozdíl v šesti znacích

Nejzrádnější na celé záležitosti bylo, že se ISO 8859-2 a windows-1250 lišily jen málo, a to právě tak, aby text na první pohled vypadal skoro dobře. Většina českých písmen (á, é, í, ó, ú, ý, č, ď, ě, ň, ř, ů i jejich velké protějšky) leží v obou tabulkách na stejných místech. Liší se jen šest českých znaků:

ZnakISO 8859-2windows-1250
ŠA98A
ŤAB8D
ŽAE8E
šB99A
ťBB9D
žBE9E

Pozice v tabulkách jsou uvedeny hexadecimálně.

Příčina je prostá: ISO 8859-2 vyhrazuje oblast 80 až 9F pro řídicí znaky, kdežto Microsoft ji využil pro tisknutelné znaky, mezi nimi právě pro písmena Š, Ť, Ž a jejich malé protějšky.

Vezměme větu „Příliš žluťoučký kůň“. Pokud je uložená v ISO 8859-2 a prohlížeč ji přečte jako windows-1250, zobrazí se „Přílią ľlu»oučký kůň“. Písmena š, ž a ť se změnila na ą, ľ a », ostatní zůstala. U velkých písmen se na místě Š objeví ©, na místě Ť znak « a na místě Ž znak ®. Opačný případ, tedy text ve windows-1250 přečtený jako ISO 8859-2, je ještě horší: odpovídající bajty patří mezi řídicí znaky, takže písmena š, ť a ž zmizí nebo se změní v prázdné čtverečky. Slováci měli navíc potíže s písmenem „ľ“, které má v každé z tabulek jinou pozici.

Čtenář se v takovém textu dokázal vyznat, ale stránka vypadala otřesně. A nejen to: vyhledávače, databáze i třídicí funkce si s takovým textem neporadily.

Prohlížeč hádá

Jak se prohlížeč dozví, v jakém kódování je stránka uložena? Podle standardu HTML rozhoduje v tomto pořadí: nejprve případná značka pořadí bajtů (BOM) na začátku souboru, poté kódování uvedené v HTTP hlavičce Content-Type a nakonec značka <meta> v prvních 1024 bajtech dokumentu. Pokud chybí všechno, spoléhá prohlížeč na odhad nebo na výchozí hodnotu podle jazyka. Pro češtinu je tou hodnotou windows-1250.

Právě tady vznikala většina potíží. Autor uvedl kódování v <meta>, jenže server posílal v hlavičce něco jiného, například kvůli direktivě AddDefaultCharset v Apache, a hlavička vyhrála. Soubor uložený ve windows-1250 a server hlásící ISO-8859-2: písmena š, ť a ž mizela. Soubor uložený v ISO-8859-2 bez jakékoli deklarace a český prohlížeč s výchozím windows-1250: na stránce se objevovala ą, ľ a ».

Nešlo jen o HTML. Data odeslaná z formuláře se posílají v kódování stránky, takže například písmeno „č“ dorazilo na server jako %E8 z ISO i WIN stránky, ale jako %C4%8D ze stránky v UTF-8. Skript na straně serveru musel vědět, s čím má co do činění, a často to nevěděl.

Uživatelé si proto osvojili rituál: otevřít nabídku Zobrazit, najít položku Kódování a zkoušet jednu možnost za druhou, tedy zhruba Středoevropské (ISO), Středoevropské (Windows) a Středoevropské (Mac). Název tohoto článku je vlastně otázka, kterou si v té nabídce kladlo mnoho lidí.

Uvozovky a pomlčky aneb proč WIN lákal

Windows-1250 měla ještě jednu výhodu, kterou si mnozí uvědomili až po čase. Obsahuje typografické znaky, které v ISO 8859-2 chybí: české uvozovky „ a “, pomlčku –, dlouhou pomlčku —, tři tečky … nebo odrážku •. Později přibylo i znaménko eura. Kdo psal text ve Wordu, dostal tyto znaky automaticky, a když je pak vložil na stránku deklarovanou jako ISO 8859-2, zmizely nebo se změnily v nesmysl.

Řešením byly znakové entity. Zápis &bdquo;, &ldquo;, &ndash; nebo &hellip; je na kódování stránky nezávislý, protože odkazuje přímo na znak v Unicode. HTML 4 tyto entity už obsahovalo. A kdo potřeboval písmeno, pro které entita neexistovala, použil číselný zápis, například &#269; pro „č“, &#345; pro „ř“ nebo &#283; pro „ě“. Stránky pak byly čitelné v jakémkoli kódování, jen se špatně udržovaly.

Mac: třetí strana sporu

U MacCE nešlo o drobné rozdíly. Tabulka je uspořádaná úplně jinak, takže i písmeno „č“ má jiný kód než v ISO a WIN. Hlavní potíž se netýkala ani tak webových serverů, které MacCE posílaly jen zřídka, jako spíše textových souborů a e-mailů, které se mezi Macem a PC posílaly sem a tam.

Se systémem Mac OS X, který vyšel v roce 2001, přešel Apple na Unicode a MacCE začalo mizet. Dnes ho moderní prohlížeče nepodporují: Encoding Standard, který popisuje chování současných prohlížečů, z Maců obsahuje jen základní západoevropskou tabulku a tu cyrilskou. Stránku v MacCE tedy moderní prohlížeč správně nezobrazí.

Mac si ale na Čechy přichystal ještě jeden dárek. Souborový systém HFS+ ukládal názvy souborů v rozložené podobě (normalizace NFD), kdy se „č“ skládá z písmene „c“ a samostatného háčku. Nahrajete-li takový soubor na server, název se může rozbít, a to nikoli kvůli kódování, ale kvůli rozdílné normalizaci.

Unicode a UTF-8: mír bez vítěze

Východisko z celého zmatku nabízel Unicode, který vznikl na počátku devadesátých let s jednoduchým cílem: dát každému znaku každého písma jedno jednoznačné číslo. Zbývalo rozhodnout, jak ta čísla ukládat. Windows NT a později Java sázely na šestnáctibitové kódování, pro web se ale prosadilo UTF-8, které v roce 1992 navrhli Ken Thompson a Rob Pike, údajně na papírovém prostírání v jedné restauraci.

Důvody vítězství byly praktické. UTF-8 je zpětně kompatibilní s ASCII: každý znak ASCII zabírá jeden bajt, takže značky HTML, hlavičky HTTP i většina zdrojových kódů zůstaly beze změny. Písmena s diakritikou zabírají dva bajty (například „č“ se zapíše jako C4 8D), čínské znaky tři a emoji čtyři. Hlavně ale UTF-8 pojme vše najednou: češtinu, polštinu, eurový znak, české uvozovky i čínštinu na jedné stránce.

Standard HTML dnes autorům doporučuje používat UTF-8 a Encoding Standard jde ještě dál: nové formáty mají podle něj používat výhradně UTF-8. Podle průzkumu W3Techs ho v říjnu 2026 používalo 99,1 % webů, jejichž kódování je známé.

Přechod ale nebyl bezbolestný. Vznikl nový druh nesmyslu: UTF-8 přečtené jako windows-1250. Písmeno „č“ se změní na „Äť“, „ě“ na „Ä›“, „ř“ na „Ĺ™“, „š“ na „š“, „ž“ na „Ĺľ“ a „á“ na „á“. Pokud tohle znáte, víte, že se někde mezi databází a stránkou pokazila deklarace.

Zbytky války dnes

Válka skončila, ale padlé jednotky se dodnes objevují.

  • Excel a CSV. Excel v českých Windows ukládá soubory CSV ve windows-1250 se středníkem jako oddělovačem. Chcete-li UTF-8, zvolte při ukládání formát CSV UTF-8.
  • Poznámkový blok. Od aktualizace Windows 10 z května 2019 ukládá soubory ve výchozím stavu v UTF-8, dřív používal windows-1250 a mnoho starých souborů to pamatuje.
  • Databáze. Starší tabulky v MySQL stále bývají v kódování latin2 nebo cp1250. Při migraci pozor: v MySQL označuje utf8 pouze tříbajtovou variantu, správná volba je utf8mb4.
  • BOM. Soubor v UTF-8 může začínat značkou EF BB BF. U skriptů v PHP to dřív způsobovalo hlášení „headers already sent“, protože se neviditelný znak odeslal dřív než hlavička.
  • Délka řetězců. V UTF-8 má funkce strlen v PHP pro „č“ hodnotu 2. Na práci s češtinou proto patří funkce s předponou mb_.

Pravidla pro přežití

  1. Používejte UTF-8 všude: v editoru, v souborech (bez BOM), v HTTP hlavičce Content-Type: text/html; charset=utf-8 i v elementu <meta charset="utf-8">, který patří na začátek <head>.
  2. V databázi použijte utf8mb4 a nastavte stejné kódování i pro spojení z aplikace.
  3. Stará data převádějte jednorázově a ze známého zdroje. Zjistit kódování pomůže příkaz file -i (na macOS file -I), převod zvládne například iconv -f windows-1250 -t utf-8 stary.txt > novy.txt.
  4. Nikdy nepřevádějte dvakrát. Dvojí převod vytvoří právě ty nesmysly typu „Ĺ™“, které se už nedají spolehlivě vrátit zpět.
  5. Testujte na větě, v níž jsou všechna písmena s diakritikou: „Příliš žluťoučký kůň úpěl ďábelské ódy“.

Kdo vlastně vyhrál?

Ani jeden ze tří táborů. ISO 8859-2 měla normu, windows-1250 měla uživatele a MacCE měla grafiky, ale žádná z nich nezvítězila. Válka skončila tím, že se bojiště zrušilo: místo aby každý bojoval za svou tabulku, přešli všichni na jednu, která pojme všechno.

Příběh je poučný i dnes. Každé rozhraní mezi dvěma systémy je místem, kde se může rozejít představa o tom, co znamenají bajty. Dobrá zpráva zní, že pro text je tahle představa už skoro všude společná. Až se vám příště na stránce místo háčku objeví „Äť“, nehledejte nepřítele. Hledejte jen místo, kde někdo zapomněl napsat, jakým kódováním mluví.

Komentáře

Odebírat
Upozornit na
guest
1 Komentář
Nejstarší
Nejnovější Nejvíce hlasů
vitsoft

Taky jsem v této „válce“ bojoval a napsal program pro vzájemný převod mezi 79 způsoby kódování včetně HTML entit: https://euroassembler.eu/eurotool/euroconv.htm
Freeware pro Linux a Windows.

Začal jako projekt studentů Matfyzu. Český BIRD dnes pomáhá řídit provoz na největších internetových uzlech

Internet drží pohromadě i díky místům, kde se propojují sítě poskytovatelů připojení, cloudů nebo videoslužeb. S předáváním informací o tom, kudy jsou jednotlivé sítě dostupné, jim ve Frankfurtu, Londýně i Amsterdamu pomáhá český BIRD. Začal jako studentský projekt, po první verzi z roku 2000 léta spíš dřímal a soustavný vývoj obnovil až CZ.NIC. Ve své úloze uspěl tak výrazně, že největší uzly nakonec začaly platit vývoj konkurenčního softwaru, aby nebyly závislé jen na něm.

WebSocket: Jak dostat webovou aplikaci do reálného času

Chat, živé notifikace, společná úprava dokumentu nebo průběžně aktualizované kurzy. Uživatelé dnes čekají, že se webová aplikace změní ve chvíli, kdy se změní data, a ne až po stisknutí klávesy F5. Protokol WebSocket je nejrozšířenější způsob, jak mezi prohlížečem a serverem vytvořit trvalý obousměrný kanál. V článku se podíváme, jak funguje pod kapotou, jak ho použít v prohlížeči i na serveru a na co si dát pozor při nasazení do produkce.