Character-Encoding: Warum “ö” manchmal als “ö” dargestellt wird

Zeichen-Codierungs-Probleme passieren erstaunlich häufig. Besonders in Sprachen, die hauptsächlich lateinische Buchstaben mit wenigen Sonderzeichen verwenden. In diesem Beitrag geht es um diese seltsamen “ö”-Symbole und was hinter den Kulissen eigentlich passiert.

Vor ein paar Wochen erhielt ich die folgende E-Mail:

„Unser Versandpartner meldet sich telefonisch oder per Mail zur Ankündigung der Lieferung. Aufgrund des großen Bestellaufkommens können wir dies aktuell jedoch nicht garantieren.“

Das ist ein sehr häufiges Encoding-Problem, was ständig auftaucht. Aber warum passiert das? Um das Problem zu verstehen, müssen wir zunächst klären, was mit Encoding gemeint ist.

Wie Computer Text darstellen: ASCII

Computer arbeiten grundsätzlich nur mit Zahlen, also muss es eine Möglichkeit geben, eine Zahl als Buchstabe, bzw. als Zeichen, zu interpretieren. Wenn man weiß, wie ein Zeichen repräsentiert wird, kann man beliebigen Text als Folge von Zahlen darstellen, auch “Strings” genannt. Diese Darstellung von Zahlen als Zeichen nennt man Character-Encoding.

Eine der einfachsten Codierungen ist als ASCII bekannt und weist jeder Zahl genau ein Zeichen zu. Obwohl ASCII-Zeichen in einem Byte gespeichert werden, das 256 mögliche Werte darstellen kann, umfasst ASCII nur 128 Zeichen. Ursprünglich wurde ein Bit zur Fehlerüberprüfung reserviert. Später wurde eine erweiterte ASCII-Version (ISO 8859-1) eingeführt, die alle 256 möglichen Zahlen nutzt. Da es nur relativ wenige sind, lassen sich ASCII-Zeichen problemlos in einer Tabelle darstellen:

Nr.ZeichenNr.ZeichenNr.ZeichenNr.ZeichenNr.ZeichenNr.ZeichenNr.ZeichenNr.Zeichen
0Ctrl-@16Ctrl-P32 48064@80P96`112p
1Ctrl-A17Ctrl-Q33!49165A81Q97a113q
2Ctrl-B18Ctrl-R34"50266B82R98b114r
3Ctrl-C19Ctrl-S35#51367C83S99c115s
4Ctrl-D20Ctrl-T36$52468D84T100d116t
5Ctrl-E21Ctrl-U37%53569E85U101e117u
6Ctrl-F22Ctrl-V38&54670F86V102f118v
7Ctrl-G23Ctrl-W39'55771G87W103g119w
8Ctrl-H24Ctrl-X40(56872H88X104h120x
9Ctrl-I25Ctrl-Y41)57973I89Y105i121y
10Ctrl-J26Ctrl-Z42*58:74J90Z106j122z
11Ctrl-K27Ctrl-[43+59;75K91[107k123{
12Ctrl-L28Ctrl-\44,60<76L92\108l124`
13Ctrl-M29Ctrl-]45-61=77M93]109m125}
14Ctrl-N30Ctrl-^46.62>78N94^110n126~
15Ctrl-O31Ctrl-_47/63?79O95_111o127DEL

Damit funktionierte die Codierung bei einfachem englischen Text gut, allerdings mit einer offensichtlichen Einschränkung. Man kann nur Zeichenfolgen darstellen, die diese 128 Zeichen enthalten. Benötigt man ein Sonderzeichen wie „ö“, bekommt man ein Problem. Es gab zwar zahlreiche lokale Varianten von ASCII, aber kein gemeinsames einheitliches Encoding. Genau hier setzt die nächste Codierung an.

Die UTF-8-Codierung

UTF-8 wurde als abwärtskompatibel mit ASCII entwickelt. Um mehr Zeichen unterzubringen, wird ein neues Konzept eingeführt: variable-width encoding. Beginnt eine Bytefolge mit einem speziellen leading byte, wird das Zeichen als 2-Byte, 3-Byte oder größer interpretiert.

Damit können ausreichend viele Zeichen abgebildet werden, während bei reinem ASCII-Text die Speicherung weiterhin effizient bleibt. Nutzt man eine Sprache mit vielen Sonderzeichen, sinkt die Speicher­effizienz, da alle Zeichen den leading byte enthalten.

Um dem entgegenzuwirken, wurde UTF-16 entwickelt, es verwendet 16 Bit bzw. 2 Bytes zur Speicherung eines Zeichens und nutzt zusätzlich die variable Breite für Sonderzeichen, die sich nicht mit 16 Bit darstellen lassen.

Wahl der falschen Codierung

Solange alle dieselbe Codierung verwenden, kann eine Nachricht problemlos versendet und verstanden werden. Probleme entstehen, wenn man in einer anderen Codierung sendet als der Empfänger erwartet.

Beispiel: Jemand sendet mir eine Nachricht in UTF-8, wobei „ö“ als Zwei-Byte-Zeichen dargestellt wird. Ich interpretiere die Bytes jedoch als eine Variante von ASCII. Das Ergebnis: Beide Bytes erscheinen als Zeichen, nämlich „Ó und „¶“.

Dasselbe kann natürlich auch umgekehrt passieren:

Beispiel: Jemand sendet mir eine Nachricht in seiner Variante von erweitertem ASCII (z.B. Windows-1252), wobei „ö“ als Ein-Byte-Zeichen dargestellt wird. Ich interpretiere dieses Byte allerdings als UTF-8. das ursprüngliche Zeichen sieht dann so aus: „�“.

Wie man es verhindern kann

Heutzutage haben sich die meisten Dienste auf UTF-8 geeinigt. Um Missverständnisse bei automatisierten Systemen zu vermeiden, werden fast alle HTTP-Nachrichten mit einem Header versehen, der den Inhalt und die Codierung benennt:

Content-Type: text/html; charset=UTF-8

Darüber hinaus kann HTML selbst ein zusätzliches Meta-Tag enthalten, um die Codierung festzulegen:

<meta charset="UTF-8">

Trotzdem muss man, um herauszufinden, welche Codierung verwendet wird, ironischer Weise erst einen speziellen Header lesen, der selbst natürlich in einer Codierung gespeichert ist.

Fazit

Im Deutschen, mit wenigen Sonderzeichen, stört es oft nicht groß, wenn Codierungs­fehler auftreten, weil der Text weiterhin lesbar bleibt. Deswegen kümmert es die meisten auch nicht, wenn sowas mal passiert.

Zurück zur ursprünglichen Nachricht: Ich bin mir ziemlich sicher, dass mein E-Mail-Client UTF-8 verwendet. Stattdessen ist wahrscheinlicher, dass ein Backend-Prozess der automatischen Mail-Verarbeitung zwischendrin von einer falschen Codierung ausgegangen ist, was anschließend zu diesem Fehler geführt hat.

Wenn du im Internet unterwegs bist, stößt du früher oder später auf solche Zeichenfehler. Beim nächsten mal, wenn du über diesen Fehler stolperst, versuch doch einmal anhand der Zeichen herauszufinden, wie die Codierung falsch gelaufen ist.