Warum „Grüße“ als „Grüße“ ankommt

« Blog · Von

Eine Nachricht wird verschickt und kommt als Grüße an. Oder als Gr??e. Oder mit kleinen Kästchen an den Stellen, wo Umlaute stehen sollten. Drei verschiedene Bilder, drei verschiedene Ursachen — und nur eine davon lässt sich noch reparieren, wenn die Nachricht einmal beim Empfänger liegt.

Was ein Zeichensatz überhaupt festlegt

Auf der Leitung fließen Bytes, also Zahlen von 0 bis 255. Welches Zeichen eine bestimmte Zahlenfolge darstellt, ergibt sich nicht aus ihr selbst — es steht in einer Vereinbarung, die getrennt mitgeteilt werden muss.

Bei einer E-Mail steht diese Vereinbarung im Content-Type, und zwar in jedem Teil der Nachricht einzeln:

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

Fehlt die Angabe, rät das empfangende Programm. Und es rät, je nach Herkunft und Voreinstellung, unterschiedlich.

Woher die à kommen

ü als UTF-8 kodiert C3 BC gelesen als UTF-8 ü gelesen als Windows-1252 ü Dieselben zwei Bytes. Nur die Annahme darüber, was sie bedeuten, ist verschieden.
Aus einem Zeichen werden zwei. Das ist das Erkennungsmerkmal: die verunstaltete Fassung ist immer länger als das Original.

UTF-8 stellt ü als zwei Bytes dar, C3 BC. Ein Programm, das dieselben Bytes für Windows-1252 hält — ein älterer Zeichensatz mit genau einem Zeichen je Byte — liest daraus zwei Zeichen: Ã und ¼.

Nach diesem Muster entsteht die ganze bekannte Familie:

GemeintBytesFalsch gelesen
äC3 A4ä
öC3 B6ö
üC3 BCü
ßC3 9Fß
„E2 80 9Eâ‚„

Das à am Anfang ist kein Zufall: Alle deutschen Sonderzeichen beginnen in UTF-8 mit dem Byte C3, und C3 ist in Windows-1252 das Ã. Wer diese Buchstabenfolge sieht, weiß damit sofort, wonach zu suchen ist.

Fragezeichen und Kästchen sind etwas anderes

Die drei Symptome aus dem ersten Absatz sind nicht drei Ausprägungen desselben Fehlers.

  • ü — falsch gelesen. Die Bytes sind unversehrt, nur die Deutung ist falsch. Das lässt sich zurückrechnen: Wer den richtigen Zeichensatz einstellt, bekommt den Text zurück.
  • ? — verloren. Der Text wurde in einen Zeichensatz umgewandelt, der das Zeichen nicht kennt. Aus ü wurde ein Fragezeichen, und aus dem Fragezeichen lässt sich nichts mehr rekonstruieren. Das ist der einzige unwiderrufliche Fall.
  • Kästchen oder Rauten. Zeichensatz und Bytes stimmen, aber die verwendete Schriftart enthält kein Bild für dieses Zeichen. Der Text ist unbeschädigt und lässt sich kopieren; nur die Anzeige versagt.

Der Unterschied entscheidet, ob es sich lohnt, das Original noch einmal anzufordern oder nicht.

Der Kopf hat eigene Regeln

Betreff, Anzeigename und Dateiname von Anhängen stehen im Nachrichtenkopf, und der darf nach dem ursprünglichen Standard nur ASCII enthalten. Deshalb gibt es dort eine eigene Umschrift:

Subject: =?UTF-8?Q?Gr=C3=BC=C3=9Fe?=

Das ist ein sauber kodierter Betreff „Grüße": Zeichensatzangabe, Verfahren, Inhalt. Ein Programm, das das versteht, zeigt den Text an. Sieht ein Empfänger diese Zeichenfolge im Klartext, hat das sendende System eine falsche Reihenfolge gewählt — kodiert, wo nicht kodiert werden sollte, oder umgekehrt.

Diese Kodierung ist unabhängig vom charset des Nachrichtentexts. Deshalb kommt der häufige Fall vor, dass der Betreff verunstaltet ist und der Text in Ordnung, oder umgekehrt. Es sind zwei getrennte Baustellen. Wie die Nachricht insgesamt in Teile zerlegt ist, steht im Artikel über MIME.

Doppelt kodiert

Der hartnäckigste Fall ist der, bei dem bereits verunstalteter Text ein zweites Mal umgewandelt wird. Aus Grüße wird dann Grüße — die Zeichenkette wächst mit jedem Durchgang.

Das passiert typischerweise in Ketten aus mehreren Systemen: Ein Formular liefert UTF-8, die Datenbank ist auf latin1 eingestellt, das Versandprogramm nimmt UTF-8 an. Jede Station tut für sich das Richtige, und am Ende steht Unsinn.

Reparieren lässt sich das nur, indem man die Kette rückwärts abläuft und die Stelle findet, an der zum ersten Mal falsch gedeutet wurde. Alles danach ist Folge.

Die Regeln, die das Problem beseitigen

  1. Überall UTF-8, ohne Ausnahme. Formular, Anwendung, Datenbank, Versand, Nachricht. Ein einziger Punkt mit einer anderen Einstellung genügt für den ganzen Effekt.
  2. Den Zeichensatz angeben, nicht voraussetzen. charset=UTF-8 gehört in jeden Textteil. Ohne Angabe rät der Empfänger, und ein Programm, das jahrelang richtig geraten hat, rät irgendwann anders.
  3. Kopfzeilen der Bibliothek überlassen. Kodierte Wörter selbst zusammenzubauen ist fehleranfällig, und jede ernstzunehmende Versandbibliothek macht es korrekt.
  4. Bei der Datenbank auf die Kodierung der Verbindung achten, nicht nur auf die der Tabelle. Eine utf8mb4-Spalte hilft nichts, wenn die Verbindung auf latin1 steht — genau dort entsteht die doppelte Kodierung.
  5. Mit echten Zeichen prüfen. Ein Testlauf mit „Test" beweist nichts. Ein Testlauf mit „Grüße, zażółć gęślą jaźń, Ελλάδα" beweist eine Menge.

Der letzte Punkt ist der billigste und wird am zuverlässigsten vergessen. Der Fehler zeigt sich ausschließlich an Zeichen, die im Testdatensatz meistens nicht vorkommen — und dann bei einem Kunden, der zufällig Schmidt-Küppers heißt.