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
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:
| Gemeint | Bytes | Falsch 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
- Überall UTF-8, ohne Ausnahme. Formular, Anwendung, Datenbank, Versand, Nachricht. Ein einziger Punkt mit einer anderen Einstellung genügt für den ganzen Effekt.
- Den Zeichensatz angeben, nicht voraussetzen.
charset=UTF-8gehört in jeden Textteil. Ohne Angabe rät der Empfänger, und ein Programm, das jahrelang richtig geraten hat, rät irgendwann anders. - Kopfzeilen der Bibliothek überlassen. Kodierte Wörter selbst zusammenzubauen ist fehleranfällig, und jede ernstzunehmende Versandbibliothek macht es korrekt.
- Bei der Datenbank auf die Kodierung der Verbindung achten, nicht nur auf die der Tabelle. Eine
utf8mb4-Spalte hilft nichts, wenn die Verbindung auflatin1steht — genau dort entsteht die doppelte Kodierung. - 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.