Das Problem
Selbst gestandene Entwickler kommen hin und wieder einmal ins Schwitzen, weil Zeichen auf der Benutzeroberfläche oder an anderer Stelle merkwürdig verfälscht zu Tage treten. Obwohl die Grundlage zur Beseitigung solcher Ärgernisse eher einfach ist, scheinen in Sachen Zeichenkodierung mehr Halbwissen und Irrglaube zu herrschen, als gut sein kann: So findet sich manche Bibliothek, die sich nicht um das Problem schert, und selbst eine fast ausschließlich für die Erstellung von dynamischen Internetseiten (!) genutzte Programmiersprache wie PHP geht mit dem Thema Zeichenkodierung bis Version 6 nicht gerade zimperlich um. Das Verwunderliche an der Sache ist: Es ist eigentlich gar nicht so schwierig! Ein wenig Rüstzeug reicht aus, um das Problem falsch interpretierter Zeichen analysieren und beseitigen zu können. Dieses wiederum lässt sich am einfachsten erwerben indem wir einen kurzen Blick zurück wagen.
Die Wurzel des Problems…

© p_a_h
Früher war ja bekanntermaßen alles besser und daher musste man sich auch nicht mit dem Problem inkompatibler Zeichenkodierungen herumschlagen. Eine Zeit lang gab es nämlich gar nicht so viele – EBCDIC dominierte auf den Großrechnern und der Rest war mit einem ganz einfachen Zeichensatz zufrieden, der sich auf bescheidene 128 Zeichen beschränkt. Die Rede ist vom allseits bekannten American Standard Code for Information Interchange, kurz ASCII.
Allerdings bestand schon damals ein Byte auf fast allen Computern aus acht Bit und darüber hinaus wollten die Computernutzer dieser Erde (es wurden ja bekanntlich immer mehr) auch diejenigen Zeichen ihrer Sprache benutzen können, die bisher nicht berücksichtigt wurden. Also wurden die durch das verbleibende achte Bit verfügbaren weiteren 128 Speichermöglichkeiten eifrig genutzt, um eigene Zeichensatztabellen oder Codepages für die nun allgegenwärtigen PCs zu erstellen. Dieser Wildwuchs wurde dann nach und nach standardisiert und die Kinder dieser Zeit (ISO-8859-X) erfreuen sich auch heute noch großer Beliebtheit. Gedanken darüber, wie man Dateien in den verschiedenen Encodings kennzeichnet, musste man sich auch nicht machen – schließlich waren die meisten Rechner nicht vernetzt, das Internet kannte – und vor allem benutzte – fast niemand, und falls man einmal doch Daten aus einem anderen Land (zum Beispiel USA) bekommen hatte, waren die Zeichensätze in den meisten Fällen kompatibel.
Mitte der Neunziger nimmt nun allerdings das Unheil seinen Lauf – die Internetnutzung explodiert, plötzlich sind die Rechner vernetzt und schicken Daten in den unterschiedlichsten Formaten hin und her. Internationale IT-Riesen hatten das Problem schon früher am Hals und schufen deshalb Unicode – vereinfacht ausgedrückt der Versuch, jedem Zeichen (allein die Festlegung dessen, was ein Zeichen ist, ist in vielen Fällen nicht gerade einfach) einen numerischen Wert (code point) zuzuweisen und seine Eigenschaften festzuhalten. Unicode an sich ist aber kein Zeichensatz – das ist ein weit verbreiteter Irrglaube, der immer wieder zu Problemen führt: Allein mit Unicode kann man Byterepräsentationen von Zeichen ableiten – womit wir wieder bei den Zeichensätzen wären…
… und zurück in die Gegenwart!
Was hat uns dieser kleine Rückblick nun an Erkenntnissen gebracht? Nun, zum einen sollte nun klar sein, dass es so etwas wie den oft beschworenen „plain text“ nicht gibt – und zum anderen, dass es – historisch bedingt – ziemlich viele verschiedene Zuordnungen von Bytes zu Zeichen gibt. Und bei dem Satz: „Diese Dateien sind Unicode-encodiert!“ werden wir jetzt auch hellhörig. Aber was ist nun genau zu tun, wenn die Zeichen auf dem Bildschirm verzerrt erscheinen?

© Karl Baron
Das Problem lösen in einfachen …
Viele Entwickler verfallen in wilden Aktionismus, wenn sie ein solches Problem behandeln. Vor allem stürzen sie sich auf die zur Verfügung stehende Funktionalität zur Behandlung von Strings, um die betreffende Zeichenkette zu manipulieren. Meist geschieht dies ohne Erfolg und immer, ohne die Quelle des Problems zu beseitigen. Schließlich ist eine Zeichenkodierung nichts anderes als ein Mapping von Bytes auf Zeichen und dieses hat zu dem Zeitpunkt, an dem der String vorliegt, schon längst stattgefunden!
Damit ist auch klar, wo der Entwickler ansetzen muss – nämlich überall da, wo Bytes zu Zeichen werden: Gemeinhin passiert das, wenn Daten von der Festplatte gelesen oder über das Netzwerk empfangen werden. Wenn an diesen Punkten von einem Encoding ausgegangen wird, das inkompatibel zu dem ist, mit dem die Daten geschrieben wurden, kann es zu Fehlern kommen. Spätestens hier stellt sich dann die Frage: In welchem Encoding liegen die Daten eigentlich vor?
Einige Formate wie XML und nahe Verwandte wie HTML bieten eine Möglichkeit, diese Information als Metadaten im Dokument zur Verfügung zu stellen – leider wird davon in vielen Fällen kein Gebrauch gemacht. Bei einer begrenzten Datenmenge mit bekannter Quelle ist es wahrscheinlich im Zweifelsfall möglich, das Encoding durch Ausprobieren herauszufinden. Was aber tun, wenn man keine Annahmen treffen kann und das Encoding unbekannt ist?
… und schwierigen Fällen.
Diese Situation ist das täglich Brot eines Browsers: Viele Webseiten zeichnen ihr Encoding nicht aus, aber der Nutzer erwartet natürlich trotzdem ein fehlerfreies Darstellen der Webseite. Das Problem scheint auf den ersten Blick nicht lösbar – ein moderner Browser löst es aber in den meisten Fällen korrekt. Wer sich für den, im übrigen sehr interessanten, wissenschaftlichen Hintergrund dieser Problemlösung interessiert, wird unter anderem hier fündig. Für den Praktiker stehen einige Open Source-Implementierungen der entsprechenden Algorithmen bereit, z. Bsp. für Python oder Java. Eine englischsprachige Einführung zum Thema, die sehr kurzweilig zu lesen ist, gibt’s auf Joel Spolsky’s Blog.