使用方法
- 「域名或字符串」默认填「中国」,光标停在这个框里直接按回车就转换一次,改动内容也会立刻重算,不必点按钮。
- 「转换方向」有两项:编码是把 Unicode 域名转成带 xn-- 前缀的 ACE 串,解码是把 ACE 串翻回 Unicode。默认编码方向,用来生成注册商表单里那串 ASCII;点「反向」把两项对调。
- 「标签长度上限校验」默认 63,范围 1 到 63。DNS 规定单个标签最多 63 字符,超了会直接报错并给出实际长度。
- 「ACE 输出大小写」默认 0(小写),可填 1(大写)。RFC 3492 的数字值大小写不敏感,A 与 a 是同一个值,所以这个选项只改显示形态,不改编码内容。
- 「批量转换」默认写好六行示例,每行一条域名,按 Ctrl+Enter(Mac 上是 Cmd+Enter)一次算完;万一被清空,点转换时会自动填回这六行。
- 结果区第一行是「输入 → 输出」,下面跟着方向、标签数与最长标签长度,再下面是批量结果逐行列出,方便直接粘进注册商表单或证书申请。
- 结果下面是一张 20 行的自检表,把 12 个常见域名与 8 个长度样本各转一遍并做往返校验,默认显示 6 行,点「加载更多」展开全部,点「导出 CSV」存成带字节序标记的表格文件。
- 输入为空、出现空标签、解码方向缺 xn-- 前缀、遇到非法字符、数字序列被截断、转换结果超过标签上限,每一条都会给出针对该情况的具体提示。
这个 Punycode 转换工具能解决什么问题
第一类是注册与解析的口径差。注册商的域名表单只收 ASCII,直接填「中国」会被拒;DNS 报文里的标签也只允许字母、数字和连字符。Punycode 就是把 Unicode 码点编成这套 ASCII 的桥:中国 编出来是 xn--fiqs8s,拿这串去填表单、写解析记录、申请证书才能通过。
第二类是多标签域名的拆分错误。域名按点分成若干标签,Punycode 是对每个标签单独算的,不是对整串算。例え.テスト 有两个标签,正确结果是 xn--r8jz45g.xn--zckzah;如果把整串当一个标签喂给编码器,产出的东西既注册不上也解析不出来。本页默认按点逐标签处理。
第三类是日志与排障。浏览器地址栏、证书里的 CN 与 SAN、DNS 查询日志里出现的往往已经是 xn-- 串,看不出原域名是哪一个。把 xn--r8jz45g.xn--zckzah 贴进来切到解码方向,就能确认它到底对应哪个域名,也能顺手核实证书签的是不是你要的那个名字。
第四类是重复编码。已经带 xn-- 前缀的串再编码一次,会叠成双重前缀,注册与解析都会失败。本页只对含非 ASCII 的标签加前缀,纯 ASCII 与已带 xn-- 的输入原样返回,绝不叠第二层前缀。
这个工具在本站也叫「Punycode转换器」,Punycode 是 RFC 3492 定义的那套把 Unicode 编成 ASCII 的 Bootstring 算法。
计算原理与变量说明
RFC 3492 把这套算法叫 Bootstring,参数一共八个:base = 36、tmin = 1、tmax = 26、skew = 38、damp = 700、初始 bias = 72、初始 n = 128、分隔符是连字符。base 是进位基数,36 对应 26 个字母加 10 个数字;tmin 与 tmax 是每一位数字取值的下限与上限;skew 与 damp 控制 bias 的收敛速度。
编码第一步是把输入里所有小于 128 的码点原样抄进输出,这些叫基本字符;只要抄出了至少一个基本字符,就在后面补一个连字符当分隔符。bücher 的基本字符是 b、c、h、e、r 五个,所以输出以 bcher- 开头;中国 没有基本字符,所以没有分隔符,输出直接是 fiqs8s。
接着按码点从小到大处理非 ASCII 字符。每一轮先在当前未处理的码点里找最小值 m,把 delta 累加 (m - n) × (h + 1),其中 n 是上一轮的码点(初始 128),h 是已经处理完的字符数;然后对每一个等于 m 的字符输出一个变长整数:每步取阈值 t(k 小于等于 bias 时取 tmin,k 大于等于 bias + tmax 时取 tmax,否则取 k 减 bias),用 base 减 t 作除数把 delta 拆成若干位数字,最后以一位小于 t 的数字收尾。
数字与字符的对应很直接:0 到 25 写成 a 到 z,26 到 35 写成 0 到 9;反过来解析时大写与小写同值,A 与 a 解出的结果一样,这正是 RFC 3492 说的解码对大小写不敏感。
bias 的更新由 adapt 负责:d 先取首次调用时的 delta 整除 700、之后取 delta 整除 2,再自加 d 整除 numpoints;然后只要 d 还大于 (36 - 1) × 26 / 2 的整除结果 455,就反复做 d 整除 35 并让 k 累加 36;最后返回 k 加上 36 × d / (d + 38) 的整除结果。damp 700 只在第一次生效,作用是把开头一批字符的定位开销摊薄。
xn-- 不是编码内容。它是 ACE(ASCII Compatible Encoding)前缀,四个字符固定不变,解码时先剥掉再跑 Bootstring。所以同一个域名在不同系统里可能写成小写或大写形式,前缀形态不同但编码内容一致。
域名级处理按点切标签。转换时把输入按点拆开逐个判断:只有含非 ASCII 字符的标签才加 xn--,已经是 xn-- 开头的不重复转换。www.liuquan.net 三个标签全是 ASCII,结果就是原串;例え.テスト 两个标签都要编码,结果是 xn--r8jz45g.xn--zckzah。
63 这个上限来自 DNS 报文格式。单个标签的长度字段只有 6 位,最大值 63;整个域名的总长上限是 253。中华人民共和国 编码后是 xn--fiq4mp3eqscr2bfxgex2c,最长标签 25,仍在 63 以内,但汉字再往上加就会很快顶到边界。
完整示例
默认示例是 中国。它没有基本字符,输出不带分隔符,结果是 xn--fiqs8s;再解回来仍是 中国,往返一致。
把输入改成 北京,得到 xn--1lq90i;改成 上海 得到 xn--fhqz97e,改成 香港 得到 xn--j6w193g。三个都是两个汉字,编码长度各不相同,因为 Punycode 编的是码点序号与插入位置,不是字符个数。
输入 例え.テスト:两个标签分别编码,得到 xn--r8jz45g.xn--zckzah,最长标签 11。整串当一个标签编码,产出的串分隔符位置会不对。
带基本字符的情况:bücher 得到 xn--bcher-kva(bcher 是基本字符,kva 编的是 ü 的位置);münchen 得到 xn--mnchen-3ya;café 得到 xn--caf-dma;ñandú 得到 xn--and-6ma2c;äöü 得到 xn--4ca0bs。
不需要转换的五种:example、liuquan、a-b-c、www.liuquan.net、xn--fiqs8s,输出与输入逐字相同。批量框默认六行的最后一行就是 xn--fiqs8s,专门用来验证这一点。
切到解码方向,输入 xn--fiqs8s 得到 中国;输入 xn--r8jz45g.xn--zckzah 得到 例え.テスト;输入 xn--fiq4mp3eqscr2bfxgex2c 得到 中华人民共和国。批量框同样按解码方向逐行处理,但每一行都必须带 xn-- 前缀。
Punycode 与 ACE 对照表
第一张表是 12 个常见域名的编码结果,第三列是把 ACE 再解回 Unicode 的回解值,用来确认往返没有改掉字符。
| 域名(Unicode) | ACE(xn--) | 回解 |
|---|---|---|
| 中国 | xn--fiqs8s | 中国 |
| 北京 | xn--1lq90i | 北京 |
| 上海 | xn--fhqz97e | 上海 |
| 香港 | xn--j6w193g | 香港 |
| 淘宝 | xn--pbt173b | 淘宝 |
| 腾讯 | xn--r70as2s | 腾讯 |
| 亚马逊 | xn--jlq480n2rg | 亚马逊 |
| 例え.テスト | xn--r8jz45g.xn--zckzah | 例え.テスト |
| bücher | xn--bcher-kva | bücher |
| münchen | xn--mnchen-3ya | münchen |
| café | xn--caf-dma | café |
| ñandú | xn--and-6ma2c | ñandú |
第二张表看长度。单个标签上限 63 字符,整个域名上限 253 字符;「最长标签」取的是转换后各标签里最长的那一个。
| 输入 | 转换结果 | 最长标签 |
|---|---|---|
| 中国 | xn--fiqs8s | 10 |
| 中华人民共和国 | xn--fiq4mp3eqscr2bfxgex2c | 25 |
| 例え.テスト | xn--r8jz45g.xn--zckzah | 11 |
| bücher | xn--bcher-kva | 13 |
| a | a | 1 |
| verylongchinesedomainlabel | verylongchinesedomainlabel | 26 |
| xn--fiqs8s | xn--fiqs8s | 10 |
| xn--1lq90i | xn--1lq90i | 10 |
读第一张表看逐标签:例え.テスト 这一行的 ACE 里有两个 xn--,正是两个标签各转一次的结果。读第二张表看长度:中华人民共和国 编完是 25 个字符,汉字越多增长越快,八个汉字就已经吃掉 63 的一大半。
结果边界、舍入与适用说明
- 输入为空时提示「输入为空,请填一个域名或字符串,例如 中国 或 xn--fiqs8s」。
- 出现空标签(连续的点、以点开头或以点结尾)时提示该域名里有空标签,并说明 DNS 标签不能为空。
- 解码方向的输入不含 xn-- 时提示输入里没有 xn-- 标签,并说明中文域名要切到编码方向。
- 解码遇到非法字符时提示「域名不是合法的 Punycode:检测到非法字符 X」,把那个字符直接显示出来。
- 解码时数字序列被截断(少了最后的结束位)时提示缺一个结束数字位,不做猜测补全。
- 转换后的最长标签超过设定的上限时,给出实际长度与上限两个数,默认上限 63。
- ACE 输出大小写只改形态不改内容,编码与解码都接受大写;批量行里某一条解析失败会带上行号与该条的具体原因。
- Punycode 只做码点编码,不做 IDNA 的映射、规范化与同形异义字检查;注册前是否可用仍以注册商的校验为准。页面不联网、不写本地存储。
常见问题
中文域名一定要转成 xn-- 才能注册吗?
提交给注册商与 DNS 的那串必须是 ASCII,所以需要转。浏览器地址栏里输入中文是另一回事:浏览器先按 IDNA 把 Unicode 映射并规范化,再编码成 xn-- 发往 DNS,地址栏通常仍显示中文。两边看到的不是同一串字符,但指向同一个域名。
为什么 例え.テスト 转出来有两个 xn--?
因为域名按点切标签后逐个转换,每个含非 ASCII 的标签各加一次前缀。例え 编成 xn--r8jz45g,テスト 编成 xn--zckzah,拼起来就是 xn--r8jz45g.xn--zckzah。把整串当一个标签编码会得到错误结果。
xn-- 串为什么有的地方大写有的地方小写?
RFC 3492 规定解码对大小写不敏感:0 到 25 既可以是 a 到 z 也可以是 A 到 Z,26 到 35 是数字,所以两种写法解出的是同一个域名。惯例输出用小写,本页的大小写选项只为对齐某些系统的显示形态。
已经带 xn-- 的域名再转一次会怎样?
不会重复编码。转换时逐个标签判断,标签里没有非 ASCII 字符就不加前缀,所以 xn--fiqs8s 的结果还是 xn--fiqs8s。如果手工在前面再拼一个 xn--,整串会被当成普通 ASCII 原样保留,注册时同样失败。
单个标签 63 字符够用吗?中文域名能放几个字?
63 是 DNS 报文里标签长度字段的硬上限。中文域名编码后每个汉字约占 4 到 5 个字符:中国 是 10,中华人民共和国 是 25。按这个速率单个标签大约能放十几个汉字,超了本页会直接给出实际长度。
解码时提示「非法字符」是怎么回事?
说明剥掉 xn-- 后剩下的串里有不属于 base36 数字表的字符。合法字符只有 a 到 z、A 到 Z、0 到 9 和作为分隔符的连字符。常见原因是复制时被截断、多了标点空格,或把 Unicode 域名直接丢进了解码方向。
这个工具免费吗?
免费,无需注册即可使用。
输入的数据安全吗?
安全。转换在当前浏览器本地完成,不会上传输入内容。
相关工具
- Base64 编码:把二进制或文本编成可打印 ASCII,和 Punycode 一样是为了适配只吃 ASCII 的通道。
- Base64 解码:把 Base64 串还原成原文,核对接口返回值时用得上。
- URL 解析:把主机名、端口、路径逐段拆开,看域名部分的编码状态很直观。
- 域名生成器:先起一批候选名,再拿回本页转成 ACE 检查长度是否超限。
- ASCII 转文本转换器:在码点与字符之间来回换算,用来核对 Punycode 编的到底是哪个码点。