Was ist Punycode?
Punycode ist eine in RFC 3492 definierte Codierungssyntax, die Unicode-Zeichenketten in den begrenzten ASCII-Zeichensatz umwandelt, der von DNS unterstützt wird. Es ist das technische Fundament, das Internationalisierte Domain-Namen (IDNs) möglich macht und Domain-Namen in jeder Sprache mit der vorhandenen DNS-Infrastruktur funktionsfähig macht.
Das Problem, das Punycode löst
Das Domain Name System wurde in den 1980er Jahren nur mit ASCII-Zeichen im Sinn konzipiert. DNS-Label können nur enthalten:
- Kleinbuchstaben (a-z)
- Ziffern (0-9)
- Bindestriche (-)
Diese Einschränkung schloss Milliarden von Internet-Nutzern aus, die das lateinische Alphabet nicht hauptsächlich verwenden. Punycode überbrückt diese Lücke, indem jede Unicode-Zeichenkette in gültige ASCII kodiert wird.
Wie Punycode-Codierung funktioniert
Punycode verwendet einen klugen Algorithmus, der ASCII-Zeichen bewahrt, während Nicht-ASCII-Zeichen in eine kompakte ASCII-Darstellung kodiert werden.
Der Codierungsprozess
1. Zeichen trennen: In ASCII und Nicht-ASCII-Zeichen aufteilen
2. ASCII kopieren: Alle ASCII-Zeichen in ihren Originalpositionen bewahren
3. Nicht-ASCII kodieren: Verwenden Sie Generalized Variable-Length Integer Encoding
4. Präfix hinzufügen: Voranstellen von "xn--" um Punycode-Codierung anzuzeigen
Beispiele
| Original (Unicode) | Kodiert (Punycode) |
|---|---|
| münchen | xn--mnchen-3ya |
| 北京 | xn--fiqs8s |
| münchen.de | xn--mnchen-3ya.de |
| 中文.com | xn--fiq228c.com |
| café.com | xn--caf-dma.com |
Das "xn--" Präfix
Das "xn--" Präfix wird ACE (ASCII Compatible Encoding) Präfix genannt. Es signalisiert DNS-Resolvern und Anwendungen, dass das Label Punycode-codierte Inhalte enthält. Dieses Präfix:
- Ist immer kleingeschrieben
- Erscheint nie in regulären ASCII-Domain-Namen
- Löst Unicode-Dekodierung in konformen Software aus
Punycode in der Praxis
Browser-Verarbeitung
Moderne Browser verarbeiten Punycode automatisch:
Benutzer gibt ein: 中文.com
Browser sendet: xn--fiq228c.com (an DNS)
Browser zeigt: 中文.com (in Adressleiste)
Entwickler-Implementierung
JavaScript (Node.js):const punycode = require('punycode/');
// In Punycode kodieren
const encoded = punycode.toASCII('münchen.de');
// Ergebnis: xn--mnchen-3ya.de
// Aus Punycode dekodieren
const decoded = punycode.toUnicode('xn--mnchen-3ya.de');
// Ergebnis: münchen.de
Python:
domain = 'münchen.de'
encoded = domain.encode('idna').decode('ascii')
# Ergebnis: xn--mnchen-3ya.de
URL-Verarbeitung
Wenn Sie mit URLs mit IDNs arbeiten:
// URL API verarbeitet Punycode automatisch
const url = new URL('https://中文.com/path');
console.log(url.hostname); // xn--fiq228c.com
console.log(url.href); // https://xn--fiq228c.com/path
Sicherheitsauswirkungen
Punycode's Fähigkeit, jedes Unicode-Zeichen zu repräsentieren, schafft Sicherheitsrisiken:
Visuelle Spoofing
Angreifer können Domains registrieren, die auf legitimen Websites identisch aussehen:
аррlе.com (kyrillisch 'а' und 'р')
apple.com (lateinische Buchstaben)
Beide werden in einigen Schriften identisch angezeigt, sind aber unterschiedliche Domains.
Browser-Schutz
Um Spoofing zu bekämpfen, implementieren Browser Schutzmaßnahmen:
1. Mixed Script Detection: Zeigt Punycode für verdächtige Domains statt Unicode an
2. Confusable Detection: Kennzeichnet Domains mit Zeichen, die wie ASCII aussehen
3. Whitelisting: Erlaubt Unicode-Anzeige nur für bekannte TLDs
Arbeiten mit Punycode in APIs
Beim Bauen von Domain-Tools:
Speichern Sie immer Punycode: Verwenden Sie die ASCII-Form intern für Konsistenz und Datenbank-Indizierung. Akzeptieren Sie beide Formen: Lassen Sie Benutzer entweder Unicode oder Punycode eingeben und konvertieren Sie nach Bedarf. Zeigen Sie Unicode an: Zeigen Sie die menschenlesbare Form in Benutzer-Interfaces an.function normalizeDomain(input) {
const punycode = require('punycode/');
// In kleingeschriebene Punycode-Form für interne Verwendung konvertieren
return punycode.toASCII(input.toLowerCase());
}
Punycode ist für die meisten Benutzer transparent, aber essentielles Wissen für Entwickler, die internationalisierte Web-Anwendungen bauen.