Punycode
Unicode ドメイン名をxn--プレフィックス付きのASCII文字列に変換するASCII互換エンコーディング。münchen.de → xn--mnchen-3ya.de。
What Is Punycode?
Punycode is an ASCII-compatible encoding algorithm for Unicode strings, defined in RFC 3492. It converts a Unicode string — potentially containing characters from any script — into a string using only ASCII letters, digits, and hyphens. Punycode is the mechanism that makes Internationalized Domain Names (IDNs) work within the ASCII-only DNS infrastructure.
A Punycode-encoded IDN label is prefixed with xn-- to mark it as an ACE (ASCII Compatible Encoding) label. The full domain münchen.de becomes xn--mnchen-3ya.de in Punycode.
The Algorithm
Punycode represents a Unicode string in two parts, separated by a hyphen:
- Basic code points (ASCII characters): copied verbatim before the final hyphen.
- Non-basic code points: encoded as delta values (variable-length integers) appended after the hyphen.
münchen → m-u-n-c-h-e-n (basic) + ü (non-basic: ü = U+00FC)
xn--mnchen-3ya
^ ^
| encoding of position and value of ü
basic chars minus ü
The algorithm uses a generalized variable-length integer (generalized variable-length quantity, or "base-36 with bias") to encode the insertion positions and code point values compactly.
Examples
# Python standard library
"münchen".encode("punycode") # b"mnchen-3ya"
"例え.jp".split(".")[0].encode("punycode") # b"r8jz45g"
# With xn-- prefix (full IDNA encoding)
"münchen.de".encode("idna") # b"xn--mnchen-3ya.de"
"例え.jp".encode("idna") # b"xn--r8jz45g.jp"
# Decoding
b"mnchen-3ya".decode("punycode") # "münchen"
b"xn--mnchen-3ya.de".decode("idna") # "münchen.de"
Common Punycode Examples
| Unicode Domain | Punycode |
|---|---|
münchen.de |
xn--mnchen-3ya.de |
例え.jp |
xn--r8jz45g.jp |
中文.com |
xn--fiq228c.com |
한국어.한국 |
xn--bj0bj06e.xn--3e0b707e |
مثال.إختبار |
xn--mgbh0fb.xn--kgbechtv |
пример.испытание |
xn--e1afmapc.xn--80akhbyknj4f |
Punycode in Browsers
Modern browsers display the Unicode form of IDN labels when the characters all come from a single script and the label passes homograph safety checks. Mixed-script domains or suspicious lookalike characters trigger display of the Punycode form as a security warning:
User types: https://münchen.de/
Browser shows: https://münchen.de/ (safe: all Latin)
DNS query: xn--mnchen-3ya.de
User types: https://pаypal.com/ (Cyrillic а)
Browser shows: https://xn--pypal-4ve.com/ (suspicious: mixed script)
Punycode for Non-DNS Uses
Although designed for DNS, Punycode can encode any Unicode string. It is sometimes used in email systems (IDNA for the domain part) and in IRI (Internationalized Resource Identifier) processing. However, other encodings like percent-encoding are preferred for URL paths and query strings.
Limitations
- Not encryption or compression: Punycode is purely a reversible encoding for ASCII transport.
- Label length: Each DNS label encoded in Punycode must not exceed 63 ASCII characters.
- Readability:
xn--fiq228c.comis meaningless to humans — the whole point of IDN display in browsers is to hide this from users.
Quick Facts
| Property | Value |
|---|---|
| RFC | RFC 3492 |
| Purpose | ASCII-compatible encoding for Unicode strings in DNS |
| Prefix for IDN labels | xn-- |
| Character set | a–z, 0–9, - |
| Encoding style | Basic ASCII copied; non-basic encoded as delta integers |
| Python codec | "punycode" (bare) or "idna" (with xn-- prefix) |
| Max encoded label | 63 ASCII characters |
関連用語
Web & HTML のその他の用語
レスポンスの文字エンコーディングを宣言するHTTPヘッダーパラメータ(Content-Type: text/html; charset=utf-8)。ドキュメント内のエンコーディング宣言より優先されます。
::beforeおよび::after疑似要素でUnicodeエスケープを使って生成コンテンツを挿入するCSSプロパティ:content: '\2713'は✓を挿入します。
CSS properties (direction, writing-mode, unicode-bidi) controlling text layout direction. Works with Unicode …
HTMLで文字をテキスト表現する方式。3つの形式:名前(&)・十進数(&)・16進数(&)。HTMLの構文と衝突する文字に必須です。
ECMAScript Internationalization API providing locale-aware string comparison (Collator), number formatting (NumberFormat), date …
CSS supports Unicode via escape sequences (\2713 for ✓), the content property …
XMLバージョンの数値文字参照:✓または✓。XMLには名前付きエンティティが5個(& < > " ')しかありませんが、HTML5は2,231個あります。
デフォルトの絵文字表示の代わりに、通常は異体字セレクター15(U+FE0E)を使って文字をモノクロのテキストグリフでレンダリングすること。
URLの非ASCII文字と予約文字を各バイトを%XXで置き換えてエンコードします。まずUTF-8に変換し、各バイトをパーセントエンコードします:é → %C3%A9。
U+2060。改行を防ぐゼロ幅文字。ゼロ幅ノーブレークスペースとしてのU+FEFF(BOM)の現代的な代替です。