Punycode - Umlaute und Sonderzeichen in Domainnamen
Im Kreuzworträtsel und bei Internet-Adressen schreibt Lieschen Müller ae, oe, ue statt ä, ö, ü. Doch eigentlich könnte sie Ihren Nachnamen auch als Domain-Namen benutzen. Möglich machts eine trickreiche Kodierung namens Punycode.
- Dr. Harald Bögeholz
Das Internet mit seinen Millionen von Rechnern kann nur deshalb so gut funktionieren, weil sich alle Beteiligten an offene Standards halten, die sehr sorgfältig entwickelt und weiterentwickelt werden. Das Domain Name System (DNS) ist ein solcher Basis-Standard: Es stellt die Verbindung her zwischen einem menschenlesbaren Domainnamen wie www.heise.de und der IP-Adresse 193.99.144.85, die der Browser braucht, um tatsächlich auf die gewünschte Website zugreifen zu können.
Da das Internet seinen Ursprung in den USA hat, erlaubt DNS nur ASCII-Zeichen in Domainnamen, genau genommen sogar nur eine bestimmte Untermenge davon. Doch das ist viel zu wenig für ein weltumspannendes Datennetz: Vor allem aus den asiatischen Ländern kam der Ruf nach den einheimischen Schriftzeichen, denn nur wenige sprechen dort Englisch.
Nun ist DNS einer der Grundpfeiler des Internet, und an diesem so radikal zu rütteln, wie es die Einbindung zigtausender neuer Zeichen erfordert, würde womöglich Erschütterungen auslösen, die hie und da etwas einstürzen lassen. Die Arbeitsgruppe für Internationalized Domain Names (IDN) der Internet Engineering Task Force (IETF) hat sich daher 2004 darauf verständigt, DNS und die anderen Basisprotokolle des Internet nicht anzurühren, sondern Sonderzeichen in Domainnamen ausschließlich auf Anwendungsebene einzuführen. Herausgekommen ist ein Standard namens Internationalizing Domain Names in Applications (IDNA), veröffentlicht als RFC 3490.
Danach ist es die Aufgabe von Anwendungsprogrammen wie Web-Browsern, einen Domainnamen mit Sonderzeichen in eine nur aus erlaubten ASCII-Zeichen bestehende kodierte Form zu überführen. Alle tiefer liegenden Protokolle wie HTTP und DNS bekommen dann nur noch Domainnamen nach den alten Standards zu sehen, und man braucht an der Infrastruktur des Internet (DNS-Server, Web-Server, Proxys etc.) nichts zu verändern.
Die Idee, Sonderzeichen irgendwie in ASCII zu verpacken, ist nicht neu. In E-Mails wird ein ö zum Beispiel zu =F6
, das "Harald Bögeholz" in meiner Absenderadresse womöglich zu =?UTF-8?B?SGFyYWxkIELDtmdlaG9seg==?=
. In HTML heiĂźe ich mit ö
oder mit ö
oder vielleicht auch mal mit ö
, und in einer URL könnte gelegentlich ein B%F6geholz auftauchen.
Bei so vielen Codes könnte man ja einfach einen der bestehenden nehmen, sollte man meinen, doch die IDN-Entwickler haben sich für Domainnamen wieder etwas Neues ausgedacht: Punycode. Wird ausgesprochen wie Unicode, und das ist kein Zufall. Der IDNA-Standard ist nämlich eine "große Lösung" und führt nicht nur die paar für Deutsche interessanten Umlaute ein, sondern den über 100 000 Zeichen umfassenden Unicode-Zeichensatz, der die Sprachen aller Herren Länder abdeckt.
Ursprünglich war Unicode ein 16-Bit-Code, was einen Vorrat von 65 536 Zeichen ermöglicht. Schon bevor alle Plätze mit Zeichen gefüllt waren, wurde aber klar, dass auch das nicht ausreichen würde, und so hat man bestimmte Wertebereiche unter 65 536 vorsorglich reserviert und den Code auf einen Zahlenbereich von null bis 0x10FFFF erweitert, also praktisch einen 21-Bit-Code. Darin sind noch längst nicht alle Plätze tatsächlich mit Zeichen belegt. Würde man nun Unicode-Zeichen naiv als Hexadezimalzahlen kodieren, so fielen allein für die Hex-Ziffern schon bis zu sechs Zeichen an, plus irgendwelche Steuerzeichen, um das Ganze kenntlich zu machen. Ein gewöhnliches ö mit einem Sechs-Byte-Code wie 0000F6 darzustellen wäre aber die reinste Platzverschwendung.
KĂĽrze WĂĽrze
Punycode wendet einige Tricks an, um eine möglichst kurze Kodierung zu erreichen. Denn ein Domainname besteht aus mehreren so genannten Domain Labels, durch Punkte getrennt und jedes Label darf gemäß DNS-Standard höchsten 63 Zeichen lang sein. Eine möglichst kompakte Kodierung war also ein wichtiges Ziel der Punycode-Definition.
Erlaubt sind im DNS nur Buchstaben, Ziffern sowie der Bindestrich; und DNS unterscheidet nicht zwischen Groß- und Kleinbuchstaben, es stehen also nur 37 verschiedene Zeichen zur Verfügung. Punycode wird auf jedes Label einzeln angewandt und nur, wenn dieses tatsächlich Sonderzeichen enthält. Aus www.bögeholz.de wird beispielsweise www.xn--bgeholz-90a.de, die Labels "www" und "de" bleiben also unverändert.
Wie das Beispiel zeigt, beginnt ein kodiertes Domain Label mit der speziellen Zeichenfolge xn--
, gefolgt von all jenen Zeichen des ursprünglichen Domainnamens, die in DNS legal sind. Nach einem weiteren Bindestrich als Trennzeichen folgt eine magische Zeichenfolge, die sowohl die Codes als auch die Positionen der Sonderzeichen enthält. Das hat zwei Vorteile: Zum einen belegen alle im DNS ohnehin erlaubten Zeichen auch im Punycode nur ein Byte, zum anderen enthalten Domainnamen aus dem europäischen Sprachraum häufig nur relativ wenige Sonderzeichen und sind daher auch in der kodierten Form halbwegs entzifferbar. Zwar sollte in einer perfekten Welt der Anwender den Punycode nie zu Gesicht bekommen, weil der Browser die schmutzigen Details vor seinen Augen versteckt, aber man kann ja nie wissen. Sollte ein Label nur aus Sonderzeichen bestehen, so folgt nach dem einleitenden Spezialstring kein weiterer Bindestrich, sondern direkt der "magische" Sonderzeichenteil.
Um diesen zu erhalten, übersetzt man zunächst die einzufügenden Sonderzeichen und ihre Positionen innerhalb des Labels in eine Folge ganzer Zahlen. Ausgehend von der Zeichenfolge ohne Sonderzeichen drückt dabei jede Zahl aus, dass an einer bestimmten Stelle ein Sonderzeichen eingefügt wird. Ein Beispiel: Der String "schööne-ümläute" enthält elf Nicht-Sonderzeichen:
Zeichen | s | c | h | n | e | - | m | l | u | t | e | ||||||||||||
Position | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Als erstes fügt man nun das Sonderzeichen mit dem kleinsten Code ein, im Beispiel "ä" (Code 228) und zwar an der Position 8. Der dafür erforderliche Zahlencode ergibt sich aus einer Tabelle:
128 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
129 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
… | … | … | … | … | … | … | … | … | … | … | … | … |
228 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 12010 | 12011 |
Um ausgehend von 128 den Code 228 einzufügen, muss man 100 Zeilen (228 - 128) à 12 Positionen nach unten gehen und dann noch 8 nach rechts, um hinter das l zu kommen. Macht einen Zahlencode von 100 · 12 + 8 = 1208.
Als Nächstes kommen die "ö"s an die Reihe (Code 246). Sie werden relativ zur letzten Einfügeposition kodiert, und da der String jetzt schon um ein Zeichen länger ist,
Zeichen | s | c | h | n | e | - | m | l | ä | u | t | e | |||||||||||||
Position | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
gilt eine neue Tabelle:
228 | 1 | 2 | 3 | ||||||||||
229 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
… | … | … | … | … | … | … | … | … | … | … | … | … | … |
246 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 |
Um von 228 nach 246 zu kommen, geht man 18 Zeilen nach unten und dann noch 6 Positionen nach links, um von der aktuellen Einfügeposition hinter dem ä zum h zu gelangen. Der nächste Zahlencode ist also 18 · 13 - 6 = 228. Das nächste ö ist einfach, denn es folgt direkt nach dem ersten und hat den gleichen Code. Die Schlüsselzahl ist daher schlicht die Null. Das noch fehlende ü (Code 252) ergibt die Zahl 93.
Die Idee hinter dieser Kodierung ist, dass sie möglichst wenige große Zahlen liefern soll, weil kleinere Zahlen sich anschließend in weniger Zeichen kodieren lassen als große. Normalerweise wird ein Domainname nur Zeichen aus einer Sprache enthalten; eine Mischung aus Arabisch und Japanisch ist doch eher unwahrscheinlich. Daher ist die erste Codezahl meist ein großer Sprung in die richtige Gegend der riesigen Unicode-Zeichentabelle, und die weiteren Sprünge zu den nächsten Zeichen sind mit großer Wahrscheinlichkeit vergleichsweise klein und von ähnlicher Größenordnung.
Der Sprung in die Tiefen des Unicode beginnt übrigens frühestens beim Zeichen 128. Das bedeutet, dass sich die ASCII-Zeichen im Bereich von 0 bis 127 mit Ausnahme von Buchstaben, Ziffern und Bindestrich nicht in Punycode darstellen lassen. Firmen, die vielleicht ein ganz gewöhnliches & oder ein + im Namen haben, müssen in ihrem Domainnamen weiterhin darauf verzichten.