Punycode - Umlaute und Sonderzeichen in Domainnamen

Seite 2: Gemischte Zahlenbasis

Inhaltsverzeichnis

Als Letztes gilt es, die Zahlenfolge 1208, 228, 0, 93 in ASCII-Zeichen zu verpacken. Auch hierbei haben die Punycode-Erfinder alle Register der Komprimierungskunst gezogen. Da 36 verschiedene Symbole (26 Buchstaben + 10 Ziffern) zur Verfügung stehen, könnte man die Zahlen einfach in einem Zahlensystem zur Basis 36 kodieren, indem man den Buchstaben a bis z die Werte 0 bis 25 und den Ziffern die Werte 26 bis 35 zuordnet. Das würde aber ein Trennzeichen erfordern, um die einzelnen Zahlen voneinander abzugrenzen.

Um das auch noch einzusparen, setzt Punycode eine Zahlendarstellung mit gemischter Basis ein, das heißt die Zahlenbasis kann sich von Stelle zu Stelle ändern, wobei jede Stelle einen Wert zwischen 0 und 35 annehmen kann, kodiert als "a" bis "9". Die letzte Zutat ist ein Schwellwert für jede Stelle, der festlegt, ob hier eine Codezahl endet oder es noch weitergeht. Eine Stelle kleiner als der Schwellwert ist die letzte Stelle der aktuellen Zahl und mit dem nächsten Codezeichen beginnt eine neue Zahl, andernfalls geht es mit der aktuellen Zahl weiter:

Codezahl 1208 228 93
Schwellwert 1 1 26 26 26 26 26 26
Wertigkeit 1 35 35² 1 10 1 1 10
Stelle 18 34 28 20 33 6
Codezeichen s 8 a 2 u a 7 g

Wenn man diesse Tabelle von unten nach oben liest, ergibt sich 18 · 1 + 34 · 35 + 0 · 352 = 1208. Hier endet die erste Codezahl, denn die letzte Stelle 0 ist kleiner als der zugehörige Schwellwert 26.

Damit es nicht zu einfach ist, ändern sich die Schwellwerte und die Zahlenbasis nicht nur von Codezahl zu Codezahl, sondern von Stelle zu Stelle. Dies genau zu erklären würde den Rahmen dieses Artikels sprengen, daher hier nur eine Andeutung der eingesetzten Heuristik: Ausgehend von der Annahme, dass die nächste Codezahl in derselben Größenordnung liegen wird wie die jeweils vorige, wählt man für die niederwertigen Stellen zunächst die Basis 35 (Schwellwert 1), um große Sprünge zu machen, und schwenkt am erwarteten Ende der Zahl über einen Zwischenschritt auf Basis 10 (Schwellwert 26), um das Ende möglichst ohne ein zusätzliches Zeichen kodieren zu können. Trotz all der Zauberei ist sichergestellt, dass jede Zahl eine eindeutige Kodierung besitzt.

Wer es genau wissen will, findet in RFC 3492 eine Beispielimplementierung als Pseudocode und in C; außerdem gibt es inzwischen mehrere kostenlose Libraries. In unserem Punycode-Online-Tool können Sie mit Punycode experimentieren. Dort kann man auch das Beispiel nachvollziehen: schööne-ümläute hat im Endergebnis den Punycode xn--schne-mlute-s8a2ua7g. Ein Label wird durch Punycode um mindestens fünf Zeichen länger. Darüber hinaus ist einem Domain Label schwer anzusehen, ob es nach der Kodierung die zulässige Maximallänge von 63 Zeichen überschreitet; hier hilft nur Probieren.

Was aber, wenn der Surfer den Domainnamen nun in GroĂźbuchstaben eingibt? DNS unterscheidet traditionell nicht zwischen GroĂź- und Kleinschreibung, und das soll natĂĽrlich auch bei Umlauten so bleiben. IDNA schreibt daher vor, dass der Domainname vor der Punycode-Kodierung in Kleinbuchstaben zu wandeln ist. Genauer: Er muss mit einem Algorithmus namens Nameprep behandelt werden (RFC 3491), der wiederum nur ein so genanntes Profil fĂĽr ein noch allgemeineres Verfahren namens Stringprep ist (RFC 3454).

Wer glaubt, das sei eine Lappalie und mit einem Federstrich à la tolower() aus der C-Library abzuhandeln, hat die große, weite Unicode-Welt mächtig unterschätzt. Der Stringprep-RFC umfasst über 90 Seiten, davon drei Viertel Tabellen, und nimmt außerdem auf weiterführende Details aus dem Unicode-Standard Bezug. Denn einen String auf das für einen Vergleich Wesentliche zu reduzieren, ihn also zu "normalisieren", umfasst nicht nur die Umwandlung von Groß- in Kleinbuchstaben.

Mit typographischen Feinheiten fängt es an: Im Unicode gibt es eigene Zeichen für Ligaturen. Der Begriff stammt aus dem Bleisatz und bezeichnet eine Zusammenfügung mehrerer Zeichen zu einem einzigen, früher einer einzigen Blei-Letter. fi, fl, ffi und ffl sind Beispiele hierfür: Bei der fi-Ligatur verschmilzt der i-Punkt mit dem Knubbel am f. Die Normalisierung zerlegt die genannten Ligaturen in ihre Einzelbuchstaben, was für unbedarfte Programmierer eine Falle bereithält: Ein String kann beim Normalisieren länger werden (aber auch kürzer).

Buchstaben mit Akzenten wie à oder ô können wahlweise als ein Zeichen oder als Zeichen + Akzent kodiert sein; die Nameprep-Normalisierung macht daraus ein Zeichen. Für die Einheit Angström gibt es ein eigenes Zeichen (U+212B), das aber genau gleich aussieht wie das gewöhnliche A mit Kringel drauf (U+01FA). Die Japaner haben Katakana-Zeichen voller und halber Breite, aber sonst gleicher Bedeutung, und in ihrer Silbenschrift unterscheidet sich ga von ka nur durch zwei zusätzliche Strichelchen, die den Konsonanten weich machen. ka + Weichmacher normalisiert also zu einem ga in voller Breite, auch wenn es ein schmales ka war. Und so gibt es hunderte weiterer Regeln.

Den deutschen Sprachraum berührt das meiste davon wenig, aber eines betrifft auch uns: Das ß wird von Unicode als Ligatur betrachtet (ist es historisch auch, nämlich aus s und z) und von Nameprep nach ss gewandelt. Dies passiert bereits vor der Punycode-Kodierung, sodass ein Domainname mit ß, der sonst keine Sonderzeichen enthält, im Klartext bleibt: Durch Eingabe von heiße-netze.de kann man schon heute auf die Domain heisse-netze.de zugreifen. Es lassen sich folglich keine Domains registrieren, die explizit ein ß enthalten – gut für die Schweizer, die das ß nicht kennen. Allerdings wird unter anderem deswegen schon über eine neue Fassung der IDNA gearbeitet.

Ganz wild wird es, wenns beispielsweise ans Arabische oder Hebräische geht, also Sprachen, die von rechts nach links geschrieben werden. Denn deren Schriftzeichen lassen sich in einem String mit von links nach rechts laufenden wie lateinischen Buchstaben mischen. Bei solch einem bidirektionalen String gibt es manchmal mehrere Möglichkeiten, in welcher Reihenfolge die verschiedenen Schreibrichtungen kodiert werden; Nameprep legt eine davon als die normale fest und verbietet die anderen, damit keine Missverständnisse entstehen.

Ein Araber muss bei der Eingabe einer URL eventuell zweimal die Richtung wechseln muss: Erst schreibt er http:// von links nach rechts, dann seinen Domainnamen von rechts nach links und schließlich hintendran noch .com von links nach rechts. Eine schöne Bescherung!

Daher arbeitet eine Arbeitsgruppe der ICANN an Top-Level-Domains (TLD, wie .de in heise.de) mit Sonderzeichen. Auch hier kommt natürlich Punycode zum Einsatz, denn die TLD ist ja nichts anderes als das letzte Domain-Label. Zu klären sind dagegen noch organisatorische Fragen wie die Zuständigkeit der Registrare: Wird man die Domain heise.dö auch beim DENIC regstrieren können?

Der IDNA-Standard wurde im März 2003 fertig gestellt, lange vor Einführung entsprechender Domains. Schon bald darauf hatten Mozilla und Opera ihn implementiert. Nur der Internet Explorer 6 schickte Domainnamen mit unzulässigen 8-Bit-Zeichen in die weite Welt, wie es ihm gerade passt, kodierte zum Beispiel in ISO 8859-1 oder UTF-8 je nach Laune und Einstellungen. Doch mit dem Internet Exploer 7 zogen auch bei Microsoft korrekt kodierte Sonderzeichen ein. Wer sich vom veralteten Internet Explorer 6 nicht trennen kann oder will, rüstet einfach ein Plugin von VeriSign nach.

Wer testen will, ob sein Browser IDN-fähig ist, kann die Seite grün.knipp.de aufrufen, die der Internet-Provider Knipp zu diesem Zweck eingerichtet hat.

Durchwachsener sieht es bei anderen Anwendungen aus, die auch Domain-Namen benutzen. So ist es mehr als vier Jahre nach der Einführung der IDNAs noch nicht selbstverständlich, dass eine E-Mail an Lieschen@müller.de korrekt versendet wird. Hier zeigt sich der Nachteil der Grundsatzentscheidung gegen Änderungen am DNS selbst: Jedes einzelne Programm muss umgebaut werden und Domain-Namen ersteinmal punycodieren. Wenn der Programmierer daran nicht denkt, oder zum Beispiel als Amerikaner gar keinen Leidensdruck verspürt, schaut der Anwender in die Röhre.