Punycode is how the internet fits internationalized domain names into the ASCII-only world of DNS. A name like münchen.example becomes xn—mnchen-3ya.example so it can be looked up, while browsers display the native form. This tool converts Unicode domains to their xn— ASCII form and decodes xn— domains back to Unicode, processing each label per RFC 3490 and RFC 3492.
How it works
The encoding follows the Bootstring algorithm with the parameters fixed for Punycode: base 36, tmin 1, tmax 26, skew 38, damp 700, an initial bias of 72 and an initial code point of 128. It first copies all the basic (ASCII) characters of a label, then encodes the non-ASCII code points by repeatedly finding the next-smallest code point, accumulating a delta, and emitting variable-length digits whose threshold adapts via the adapt function. Decoding reverses this exactly, rebuilding the original code points one insertion at a time.
The IDN layer wraps Punycode: each dot-separated label is examined, and only labels containing non-ASCII characters are encoded and given the xn-- prefix. Pure-ASCII labels and the dots themselves are untouched, which is why a domain like shop.münchen.example only transforms the middle label.
Worked examples
A few conversions illustrate how labels are handled independently:
| Unicode domain | Punycode / ACE form |
|---|---|
| münchen.de | xn—mnchen-3ya.de |
| 日本語.jp | xn—wgv71a309e.jp |
| café.example | xn—caf-dma.example |
| bücher.de | xn—bcher-kva.de |
| shop.münchen.example | shop.xn—mnchen-3ya.example |
Notice in the last row that shop is already ASCII so it passes through unchanged, while only the münchen label gets encoded and prefixed.
Security: the homograph attack
The most practically important use of the decode direction is catching homograph attacks — phishing domains that substitute look-alike Unicode characters for familiar Latin ones. For example:
- A Cyrillic
а(U+0430) looks identical to a Latina(U+0061) in most fonts. pаypal.comwith a Cyrillic а encodes toxn--pypal-4ve.com, which immediately reveals the deception.- Greek, Armenian, and several other scripts contain characters visually indistinguishable from Latin letters.
Pasting a suspicious xn-- link here decodes it to the true Unicode, making any substitution visible before you click.
Practical notes for developers
When you need an IDNA-safe domain in code, most language runtimes provide a built-in conversion — Python’s encodings.idna, Java’s IDN.toASCII, and Node.js via url.domainToASCII. This tool is useful for quick manual checks, debugging DNS records, and verifying that a TLS certificate’s SAN matches the Punycode form a resolver would actually see. Full IDNA2008 (RFC 5891) adds Unicode normalization (NFC) and mapping before encoding, so for production validation pair this with a normalization step to catch pre-composed versus combining character differences.
Two encoding standards coexist: IDNA2003 (RFC 3490/3492) and IDNA2008 (RFC 5891). They differ in how they handle certain Unicode characters, particularly letters added in Unicode updates after 2003. Most browsers moved to IDNA2008 or a compatibility hybrid. For domains registered in non-Latin scripts, always test the encoded form in your target registry and browser combination to confirm the two standards agree on the label.
All encoding and decoding in this tool happens in your browser — no domain names are transmitted anywhere.