Punycode
Punycode 是一种把 Unicode 字符串可逆地转换成仅含 ASCII 字母、数字和连字符的编码算法,定义于 RFC 3492。它的核心用途是让域名能够表示中文、日文、阿拉伯文等非 ASCII 字符,因为 DNS 底层只识别 a-z、0-9 和 - 这套字符(俗称 LDH)。
在国际化域名(IDN)里,Punycode 通常配合 IDNA 规范使用:每个含非 ASCII 字符的域名标签(两个点之间的部分)会被单独编码,并加上 xn-- 前缀。例如 中国 编码为 xn--fiqs8s,münchen 编码为 xn--mnchen-3ya。整个过程是无损的、可双向还原的。
使用中的几个常见误区:
xn--前缀属于 IDNA/IDN 的约定,并不是 Punycode 算法本身的一部分;- 编码以「标签」为单位逐段进行,而不是把整条域名一起编码,点号不参与转换;
- 不同 Unicode 字符可能长得几乎一模一样(同形异义字),常被用来伪造域名钓鱼,因此浏览器有时会直接显示
xn--形式而非还原后的文字。
常见问题
Punycode 和 URL 编码(百分号编码)是一回事吗?
不是。URL 编码用 %xx 处理路径、查询串里的特殊字符;Punycode 专门用于域名标签,把非 ASCII 文本整体重新编码为 xn-- 形式。两者算法不同,作用的位置也不同。
为什么有的浏览器把域名显示成 xn-- 而不是中文?
这是防钓鱼措施。当域名中的字符可能与知名域名产生同形混淆(homograph 攻击)时,浏览器会显示原始的 Punycode 形式,让用户能看出异常,而不是被伪装成正常文字。
电子邮箱地址 @ 后面的域名也用 Punycode 吗?
是的,邮箱的域名部分同样按 IDNA 处理并转成 xn-- 形式。但 @ 前面的本地部分不走 Punycode,要直接使用 Unicode 需要 SMTPUTF8 等扩展支持。