
Punycode / IDN Converter
Encode Unicode domain names to Punycode (xn--) or decode them back. RFC 3492 compliant.
Last reviewed: April 2026New to this tool? Click here for instructions
How to Use the Punycode Converter
To use the Punycode Converter, follow these steps:
1. Choose a direction: "Unicode → Punycode" converts an IDN domain to its xn-- form; "Punycode → Unicode" reverses it.
2. Enter your domain - e.g., münchen.de or xn--mnchen-3ya.de.
3. See the result - both forms are shown side by side with immediate feedback.
When to Use the Punycode Converter in Real Workflows
Use the Punycode Converter when working with internationalized domain names (IDN) that need to be converted to ASCII-compatible format.
This tool is useful for developers, administrators, and anyone who needs to handle IDN domains in their workflows.
How the Punycode Converter Works
Punycode uses a clever algorithm to convert non-ASCII labels to a compact ASCII representation prefixed with xn--.
The algorithm first extracts the basic ASCII characters and places them at the start of the encoded output, then encodes the non-ASCII characters using a variable-length integer scheme called "generalized variable-length integers."
Tips, Edge Cases, and Limitations
Punycode can be misused in homograph attacks, so always verify the Punycode form of unfamiliar domains before clicking.
Use our URL Encoder alongside this tool for full URL analysis.
Frequently Asked Questions
Convert internationalized domain names between Unicode and ASCII-compatible Punycode (xn--) encoding instantly in your browser. Whether you're registering a German münchen.de domain, debugging a suspicious Cyrillic lookalike, or processing a batch of IDN hostnames in your application, this tool implements RFC 3492 Bootstring encoding with no server round-trips and no logging.
What Is Punycode and Why Do Internationalized Domains Need It?
The Domain Name System was designed in the early 1980s for a predominantly English-speaking internet. RFC 1035 §2.3.4 restricted hostname labels to letters (A–Z), digits (0–9), and hyphens — the LDH rule. Every byte was assumed to be 7-bit ASCII. That constraint held for two decades, but as the internet expanded into Arabic, Chinese, Cyrillic, and hundreds of other scripts, DNS had no mechanism to carry non-ASCII labels natively.
From ASCII-only DNS to Internationalized Domain Names
The solution was a two-layer approach: keep DNS itself ASCII-only, but define a reversible encoding that maps any Unicode string to a valid ASCII label. RFC 3492, published in March 2003, defines that encoding: Punycode. A Unicode domain label is transformed into an ASCII string, the prefix xn-- is prepended, and the result is a legal DNS label that any legacy resolver can handle without modification. The original Unicode form exists only at the application layer — what ICANN calls the Internationalized Domain Name (IDN).
The xn-- ACE Prefix Explained
xn-- is the ASCII Compatible Encoding (ACE) prefix. Its sole job is to tell a DNS-aware application "this label was produced by Punycode encoding; to display it, reverse the Bootstring algorithm." The prefix is always exactly those four characters: lowercase x, lowercase n, hyphen, hyphen. When a label contains only ASCII-LDH characters, the prefix is never added — de stays de, but münchen becomes xn--mnchen-3ya.
IDNA2003 vs IDNA2008: What Changed
The original IDNA standard (RFC 3490, sometimes called IDNA2003) used NFKC normalization and allowed a broad set of Unicode characters, including some symbols and compatibility characters. IDNA2008, defined across RFC 5890–5894, tightened the rules considerably: labels must be NFC-normalized, every character must be PVALID (essentially letters or digits in their script), and several character classes permitted by IDNA2003 — including the German sharp-s ß as a deviation character, most symbols, and broadly-permitted combining marks — are now disallowed or handled differently. This divergence has real-world consequences: IDNA2003 maps ß to ss before encoding, while IDNA2008 treats ß as PVALID and encodes it directly. The WHATWG URL Standard §3.5 governs how modern browsers parse and display IDN hostnames, and implementations vary in which version of IDNA they follow internally.
How to Use the Punycode Converter
Encoding Unicode to Punycode
Paste or type a Unicode domain — for example, münchen.de — into the input pane. Select Encode (Unicode → Punycode) from the direction toggle. The tool fires conversion automatically as you type, or you can click Convert manually. The ACE-encoded result appears in the right pane: xn--mnchen-3ya.de. Use the Copy button to grab the output for your registrar or application config, or Download to save a .txt file.
Decoding xn-- Back to Unicode
Switch the direction toggle to Decode (Punycode → Unicode), paste an xn-- domain such as xn--caf-dma.fr, and the tool reverses the Bootstring algorithm to produce café.fr. Labels that are already plain ASCII pass through unchanged — .fr needs no decoding.
Batch Mode: Converting Multiple Domains at Once
Enter one domain per line in the input pane. Each line is processed independently and the output maps 1-to-1 — line 3 of input yields line 3 of output. This is useful for scanning a DMARC report's domain list or verifying a bulk import file before submitting to a registrar API.
Try Example Button
The Try Example button pre-fills café.fr in encode mode, giving immediate orientation without requiring a Unicode keyboard. The tool runs 100% client-side — no domain names are transmitted or logged anywhere outside your local browser session. 🔒
Worked Example: Encoding and Decoding Real IDN Domains
Inputs
- Input 1 (Encode)
münchen.de- Input 2 (Encode)
café.fr- Input 3 (Encode)
中国.cn- Input 4 (Encode)
москва.рф- Input 5 (Decode)
xn--caf-dma.fr
Step-by-Step Walkthrough
- münchen.de — Encode. Paste
münchen.deinto the input pane with direction set to Encode (Unicode → Punycode). - Label splitting. The tool splits on
., isolating the labels['münchen', 'de']. Each label is processed independently. - ASCII label pass-through.
decontains only ASCII-LDH characters — it is returned unchanged. - Bootstring encoding of 'münchen'. Per RFC 3492: the ASCII characters
m,n,c,h,e,nare output first, followed by the delimiter-. The sole non-ASCII characterü(U+00FC) is then encoded as a delta value, producing the suffix3ya. The ACE prefix is prepended, givingxn--mnchen-3ya. - Labels rejoined. Labels are rejoined with
.→xn--mnchen-3ya.de. - Batch encode for café.fr, 中国.cn, and москва.рф. The same process runs for each line. For
москва.рф, both labels contain non-ASCII characters — the TLDрфencodes separately asxn--p1ai, so both labels receive thexn--prefix:xn--80adxhks.xn--p1ai. - Decoding xn--caf-dma.fr. Switch direction to Decode. The tool detects the
xn--prefix on the first label, strips it, and reverses the Bootstring delta forcaf-dma: the ASCII charactersc,a,fare read directly; the delta after the delimiter encodesé(U+00E9), yieldingcafé. The label.frhas no prefix and passes through as-is →café.fr.
Expected Output
xn--mnchen-3ya.de
xn--caf-dma.fr
xn--fiqs8s.cn
xn--80adxhks.xn--p1ai
café.fr
Punycode Encoding Examples: Real Internationalized Domains
The four example domains above cover Latin-with-diacritics and Cyrillic, but Punycode handles every Unicode script. The table below extends coverage across ten scripts; values are verifiable against live DNS or the RFC 3492 §7 test vectors.
Latin with Diacritics (German, French)
German and French domains are the most common entry point for developers unfamiliar with IDN. münchen.de → xn--mnchen-3ya.de is effectively the "Hello World" of Punycode — RFC 3492 §7.1 cites München (capitalized) as a reference encoding example. café.fr → xn--caf-dma.fr illustrates that a single accented character late in the label still triggers the full ACE prefix. There is no shortcut for "mostly ASCII" labels: any non-ASCII character forces encoding of the entire label.
CJK Domains (Chinese, Japanese)
CJK scripts produce the most dramatic ACE expansions. 中国.cn — "China" in Chinese — encodes to xn--fiqs8s.cn. The TLD .cn remains ASCII. 日本語.jp ("Japanese language") encodes to xn--wgv71a309e.jp. A three-character CJK label expands to a nine-character ACE suffix — each CJK code point requires more delta bits than a Latin diacritic because the code point values are much higher in Unicode space. The 63-octet label limit (RFC 1035 §2.3.4) rarely causes problems for human-readable CJK domains, but programmatically generated labels with many CJK characters can breach it.
Cyrillic Domains (Russian)
москва.рф — "Moscow.ru" in Cyrillic — produces xn--80adxhks.xn--p1ai. Both the second-level label and the country-code TLD рф are non-ASCII, so both receive xn-- prefixes. This catches developers off guard: code that strips only the first ACE prefix will pass the TLD through garbled. Always process every dot-separated label independently.
Right-to-Left Scripts (Arabic)
Arabic bidirectional domains follow the same Punycode mechanics despite their right-to-left reading order. مصر.مصر — Egypt in Arabic, used for the .eg ccTLD equivalent — encodes to xn--wgbh1c.xn--wgbh1c. When both SLD and TLD spell the same word, both ACE forms are identical. ICANN's BIDI requirements (RFC 5893) add additional constraints on label ordering in right-to-left contexts, but those constraints operate at the registry policy level, not at the Punycode algorithm level.
| Unicode Domain | Punycode (ACE Form) | Script / Language | TLD Also Encoded? |
|---|---|---|---|
| münchen.de | xn--mnchen-3ya.de | Latin (German) | No |
| café.fr | xn--caf-dma.fr | Latin (French) | No |
| 中国.cn | xn--fiqs8s.cn | CJK (Chinese) | No |
| москва.рф | xn--80adxhks.xn--p1ai | Cyrillic (Russian) | Yes |
| 日本語.jp | xn--wgv71a309e.jp | CJK (Japanese) | No |
| مصر.مصر | xn--wgbh1c.xn--wgbh1c | Arabic (Egyptian) | Yes |
| 한국.한국 | xn--3e0b707e.xn--3e0b707e | Hangul (Korean) | Yes |
| ελλάδα.gr | xn--hxajbheg2az3al.gr | Greek | No |
| ישראל.il | xn--4dbrk0ce.il | Hebrew | No |
| brasil.br | brasil.br | Latin (Portuguese) | No — all ASCII |
brasil.br row illustrates that a Latin domain with no diacritics requires no encoding.Decoding xn-- Domains Back to Unicode
When to Decode
Decoding is the right operation any time you receive a raw DNS response, parse a server access log, or inspect an email header containing an unfamiliar xn-- string. Registrar APIs, WHOIS services, and some CDN dashboards expose the ACE form rather than the Unicode display form, so programmatic decoding is a routine data-pipeline step for anyone working with international traffic.
Why Browsers Sometimes Show xn-- Instead of Unicode
Browsers apply the WHATWG URL Standard §3.5 "domain to Unicode" algorithm before rendering a hostname in the address bar. Chrome and Firefox display the decoded Unicode form when a label's characters all belong to a single Unicode script and pass a character-level allow-check. If the decoded label mixes characters from multiple scripts — combining Latin and Cyrillic in the same label, for instance — the browser falls back to displaying the raw xn-- form as a homograph-mitigation measure. This is intentional: a visually decoded label in the address bar would be indistinguishable from a legitimate domain. Safari uses a per-locale allow-list approach rather than a script-consistency check, which means the same domain may render as Unicode in Safari but as xn-- in Chrome.
Partial Decoding: Mixed Unicode/ASCII Labels
Decoding operates label by label, so partially-encoded domains are handled cleanly. xn--mnchen-3ya.de decodes the first label to münchen and returns .de unchanged — the output is münchen.de. An all-ASCII label lacking an xn-- prefix is not an error; the tool recognizes it needs no decoding. Security researchers decode unknown xn-- domains to check for lookalike characters — a practice described in more detail in the homograph section below.
Homograph Attacks and Domain Spoofing: The Security Angle
What Is a Homograph Attack?
A homograph attack registers a domain that is visually identical — or nearly identical — to a legitimate domain, using Unicode characters from a different script to achieve the resemblance. The attack exploits the fact that human readers recognize letter shapes, not Unicode code points. The most dangerous substitutions pair characters from Cyrillic, Greek, or other scripts with their visually-identical Latin counterparts. U+0430 CYRILLIC SMALL LETTER A looks identical to U+0061 LATIN SMALL LETTER A in most fonts. A domain composed entirely of such substitutions can fool casual inspection completely.
Famous Examples: Cyrillic 'а' vs Latin 'a'
In April 2017, security researcher Xudong Zheng demonstrated that the domain аррӏе.com — composed entirely of Cyrillic characters — rendered as apple.com in Chrome and Firefox before patches were applied. The Punycode form of that domain is xn--80ak6aa92e.com. Pasting xn--80ak6aa92e.com into this decoder immediately reveals the Cyrillic characters, making the substitution obvious. Chrome's fix was to display the raw xn-- form whenever a label is composed of characters from a single non-Latin script that would appear deceptively Latin when rendered. ICANN has required single-script labels in new gTLD registrations since 2012, but that rule is enforced at registry policy level, not at the DNS protocol level.
Using This Tool to Detect Lookalike Domains
The workflow for detecting a suspicious domain is straightforward: paste the xn-- form into the decoder, then inspect each character in the output against its Unicode code point. Copy the decoded output and paste it into a Unicode inspection tool, or cross-reference against the Unicode confusables database at unicode.org/reports/tr39/. That database lists every pair of characters that are visually similar across scripts. A domain containing any cross-script pair from that list warrants further investigation. The IDN Validator on this site runs IDNA2008 PVALID checks and script-consistency checks in one pass, complementing manual code-point inspection.
ICANN and Registry-Level Mitigations
Registries enforcing IDNA2008 reject mixed-script labels at registration time, which blocks the most obvious attacks at source. However, IDNA2008 enforcement is uneven: not all ccTLDs have migrated from IDNA2003, and legacy registrations from before 2012 may still exist. The practical defense for end users is browser-side: modern Chrome, Firefox, and Edge all display raw Punycode when homograph-mitigation heuristics fire. For security teams monitoring phishing infrastructure, decoding every xn-- domain in a threat feed is a non-negotiable baseline step.
The RFC 3492 Algorithm: How Punycode Encoding Works
Generalized Variable-Length Integers (Bootstring)
RFC 3492 §5 describes Punycode as a specific instance of the more general Bootstring algorithm. The core insight is that a label containing mostly ASCII characters needs to transmit only the positions and values of the non-ASCII code points — the ASCII backbone is already recoverable from the output prefix. Encoding proceeds in two phases. First, all ASCII characters in the label are copied to the output verbatim. If any non-ASCII characters exist, a delimiter hyphen is appended after the last ASCII character. Second, the non-ASCII code points are encoded as a sequence of delta values using a generalized variable-length integer (GVLI) scheme. Each delta represents the distance — in sorted code-point order — from the previously encoded code point to the next one.
Bias Adaptation Function
The bias adaptation function (RFC 3492 §6.1) adjusts the number of bits used per delta after each code point is encoded. When the encoder has just processed a small delta (meaning successive non-ASCII characters are numerically close together, as is common in a single-script label), the bias shifts to use fewer bits per digit — an efficiency gain analogous to run-length encoding. This prevents excessively long ACE suffixes for labels whose non-ASCII characters cluster in a narrow Unicode range, which is the typical case for single-language domains.
Encoding a Single Label Step by Step
RFC 3492 §7 includes test vectors for verifying any implementation. For münchen (label only, before the xn-- prefix is added): the ASCII characters m, n, c, h, e, n are output first, the delimiter - is appended, then the delta for ü (U+00FC) is encoded as 3ya, producing the Bootstring output mnchen-3ya. Prepending the ACE prefix yields the final DNS label xn--mnchen-3ya. The DNS label length limit is 63 octets in ACE form (RFC 1035 §2.3.4), and the total domain (all labels plus dots) may not exceed 253 characters in ACE form. Both constraints apply to the encoded output, not the Unicode input.
| Domain Label | Unicode Characters | ACE Punycode Characters (label only) |
|---|---|---|
| münchen | 7 | 14 |
| café | 4 | 10 |
| 中国 | 2 | 8 |
| москва | 6 | 14 |
| 日本語 | 3 | 13 |
| مصر | 3 | 9 |
| 한국 | 2 | 10 |
| ελλάδα | 6 | 18 |
xn-- prefix (4 chars) added to the final DNS label.Common Pitfalls When Working With IDN and Punycode
Forgetting to Encode Each Label Separately
The most frequent developer mistake is treating the entire domain string as a single encoding unit. münchen.de does not become xn--mnchen-3ya — it becomes xn--mnchen-3ya.de. Each dot-separated label is processed independently; the dots are delimiters, not characters to encode. When building a Punycode routine from scratch, split on . first, encode each segment, then rejoin. The same rule applies in reverse during decoding.
Case Folding and Normalization (NFC vs NFKC)
IDNA2008 requires NFC normalization before encoding; IDNA2003 used NFKC normalization. For most common characters the results are identical, but divergence occurs for characters like the German sharp-s ß: IDNA2003 maps ß to ss before encoding (so straße.de → strasse.de), while IDNA2008 treats ß as PVALID and encodes it directly. Applications targeting a mix of older IDNA2003 registrars and modern IDNA2008 registries must handle this deviation character explicitly. The Unicode Consortium's list of such "deviation characters" — those whose treatment differs between IDNA2003 and IDNA2008 — is small but consequential.
Emoji Domains: What Actually Works
The RFC 3492 algorithm encodes any Unicode code point, including emoji. The pizza emoji 🍕 encodes to xn--vi8h as a label. However, ICANN-accredited gTLD registries reject emoji labels under IDNA2008 PVALID policies — emoji are neither letters nor digits in their Unicode script. Some ccTLD operators have adopted their own policies; 🍕.ws is a genuine real-world example of an emoji domain that resolves. Before attempting an emoji domain registration, confirm the target ccTLD's IDN table explicitly permits the relevant emoji code points.
Leading/Trailing Hyphens and the Double-Hyphen Rule
RFC 5891 §4.2.3.1 prohibits labels from beginning or ending with a hyphen. Additionally, hyphens in positions 3 and 4 of a label signal the ACE prefix — which is why any label starting with xn-- is interpreted as Punycode-encoded, and why ASCII-only labels must not have hyphens at positions 3 and 4 (they would be misread as a Punycode label). This double-hyphen rule also affects U+200C (ZWNJ) and U+200D (ZWJ), which are permitted in specific script contexts under IDNA2008 — ZWJ in Devanagari half-form conjuncts, for example — but were allowed broadly under IDNA2003. Passing ZWNJ or ZWJ through a naïve encoder can produce output that a strict IDNA2008 registry rejects.
| Aspect | IDNA2003 (RFC 3490) | IDNA2008 (RFC 5890–5894) | Practical Impact |
|---|---|---|---|
| Normalization form | NFKC | NFC | Compatibility characters map to base forms in IDNA2003 but are rejected in IDNA2008 |
| German ß | Mapped to ss (deviation character) |
PVALID; encoded directly | Same input may produce different domains in each standard |
| Emoji | Allowed (encodes as-is after NFKC) | Disallowed (not PVALID) | Emoji labels accepted by IDNA2003 registrars are rejected by IDNA2008 registries |
| Symbol characters | Many allowed via Unicode category checks | Rejected unless PVALID | Trademark symbols, currency signs, etc. not registrable under IDNA2008 |
| ZWJ / ZWNJ | Broadly allowed | Allowed only in specific script contexts (Devanagari, Arabic, etc.) | Script-context validation required; naïve encoding may produce invalid labels |
| Compatibility characters | Mapped to base form | DISALLOWED | Half-width/full-width variants not encodable under IDNA2008 |
| Browser adoption | Older IE, Safari (partial) | Chrome, Firefox, Edge, modern Safari | Inconsistent rendering on legacy browsers; WHATWG URL Standard uses IDNA2008 via UTS46 |
| Registry enforcement | Pre-2012 gTLDs, many older ccTLDs | New gTLDs post-2012, ICANN-mandated registries | Confirm which standard applies to your target TLD before submitting IDN labels |
Related Domain and Encoding Tools
Punycode handles the hostname component of a URL, but a complete domain workflow often requires adjacent operations. The URL Encoder / Decoder handles percent-encoding of path segments, query strings, and fragment identifiers — entirely distinct from Punycode, which operates only on hostname labels. To verify whether a decoded IDN label meets IDNA2008 PVALID requirements before submission to a registrar, the IDN Validator runs the full character-category and script-consistency checks. For live infrastructure work, the DNS Lookup Tool lets you query A, AAAA, MX, and TXT records for any ACE-encoded domain directly in the browser. Domain Availability Checker connects to WHOIS to confirm whether an internationalized domain is already registered.
Base64 encoding comes up frequently alongside Punycode when working with JWT headers or SAML assertions that contain domain claims — both encoding types appear in the same payloads but serve completely different purposes.