UTF-8, Latin1 aka ISO-8859-1 und das Euro-Zeichen

Um mal gleich mit der Tür ins Haus zu fallen: Es gibt kein Euro-Zeichen im ISO-8859-1-Zeichensatz (aka Latin1) - und folglich sind alle Versuche, einen Text mit dem niedlichen Kniddel-E von UTF-8 oder jedem anderen Zeichen-Encoding nach Latin1 zu konvertieren zum Scheitern verurteilt. Mit etwas Glück kommt dabei ein Fragezeichen oder immerhin noch Gekröse raus. Korinthenkacker wie iconv dagegen stellen einfach ganz die Arbeit ein und man endet in einem Fehler.

Latin1 soll also kein Euro-Zeichen enthalten, hmm? Warum kann ich dann das “€” in Webseiten sehen, die ISO-8859-1 kodiert sind?

Tja… Sagen wir mal so: Es ist heute ganz einfach, durch ganz Europa zu reisen und seine Euros fröhlich überall auszugeben. Das heißt aber nicht, dass ein Grenzer einen nicht trotzdem stundenlang mit Formalitäten an der Grenze festhalten könnte.

Das ist bei Computern nicht groß anders: Es gibt freundliche Programme, die versuchen, das Leben angenehm zu machen, etwa indem sie Konventionen gelten lassen. Eine solche Konvention sagt, das man das Zeichen 128 im Latin1-Zeichensatz durch das Euro-Symbol ersetzt hat.

“Man” ist in diesem Fall eine große Koalition aus Software- und Hardware-Herstellern. Schließlich musste bei der Einführung des Euros eine einfache und billige Lösung her. Die Vorteile liegen auf der Hand: die Programme selber müssen nicht geändert werden, es braucht lediglich eine neue Schrift. Die Nachteile der Lösung kennt jeder, der beim Drucken auf älteren Druckern auf die installierten Schriften des Druckers zurück greifen muss, die das Euro-Zeichen leider nicht kennen.

Auf der anderen Seite gibt es Programme, die penibel auf die Einhaltung der Regeln pochen: bürokratisch, humorlos. Wie zum Beispiel die Programme, die Zeichenkodierungen konvertieren.

Diese argumentieren, ISO-8859-1 enthalte ganz offensichtlich kein Euro-Zeichen (bei der Festlegung von ISO-8859-1 gab es noch keinen Euro) und gleich dreimal nicht an Position 128. Stattdessen gäbe es doch die Kodierung ISO-8859-15, diese definiere ein Euro-Symbol und sei doch auch bereits seit 1999 gültig.

Und das ist natürlich nicht verkehrt. ISO-8559-15 enthält einen Euro, und zwar an Position 164. Damit sind ISO-8859-15 und ISO-8859-1 (Euro-tauglich) euro-mäßig wiederum nicht kompatibel. Das wäre ja auch zu einfach, erklärt sich aber vielleicht daraus, dass bei Latin1 an Position 164 noch dieses Zeichen steht: ¤. Das ist das internationale Währungszeichen - süß, nicht wahr? Besser bekannt ist dieses Zeichen freilich als Tabellenzellen-Ende-Zeichen aus Microsoft Word und anderen Textverarbeitungen. Genau so gut hätte man vorschlagen können, das Symbol ¶ durch den Euro zu ersetzen.

ISO-8859-15 jedenfalls ist ein lustiger Geselle, von dem man noch nicht mal weiß, ob er nun Latin0 oder Latin9 heißt. Man weiß jedoch, dass er eigentlich Latin1 hatte ersetzen sollen. Daraus ist allerdings nichts geworden, wenn wir uns zum Beispiel PHP, QT oder andere Programmiersprachen und -frameworks ansehen. Latin1 ist immer noch omnipräsent.

Wer sich aber Ärger ersparen will, der greift fortan auf ISO-8859-15 zurück.

Aus all dem folgt also, dass Code wie der folgende - der einen UTF-8 Text annimmt und eine Latin1-Mail verschickt - in die Katastrophe führen, wenn der Text ein Euro-Zeichen enthält:

<?php
function send_mail($to, $subject, $utf8_message) {
  //falsch!
  $latin_message = @iconv('UTF-8', 'ISO-8859-1', $utf8_message);
  // auch falsch!
  $latin_message = @utf_decode($utf_message);
  mail($to, $subject, $latin_message);
}

Hier ist die richtige Version. Da wir latin0-oder-9 verwenden, müssen wir das beim Verschicken der Mail irgendwie mitteilen, also auch einen entsprechenden Header dazupacken:

<?php
function send_mail($to, $subject, $utf8_message) {
  $latin_message = @iconv('UTF-8', 'ISO-8859-15', $utf8_message);
  $header = 'Content-Type: text/plain; charset=ISO-8859-15';
  mail($to, $subject, $latin_message, $header);
}

Published: November 18 2006