fbpx
维基百科

国际化域名编码

国际化域名编码[1](英語:Punycode)是一种表示Unicode码和ASCII码的有限的字符集。例如中文上海”会被编码为“fhqz97e”。

Punycode的目的是在于国际化域名标签(IDNA)的框架中,使这些(多语言)的域名可以编码为ASCII。编码语法在文档 RFC 3492 中规定。

编码过程 编辑

RFC 3492中说明:Punycode是一种称为Bootstring的更普遍的算法实例,它允许由部分基本的编码集合组成的字符串唯一表示由更大编码集合组成的任何字符串。配合Unicode文本的特性,Punycode定义了一般Bootstring算法的参数。本节以德语字符串"bücher"(书籍)为例,演示Punycode的编码过程,该字符串被编码为"bcher-kva"。

分离ASCII字符 编辑

首先,字符串中的所有ASCII字符将被直接从输入复制到输出,任何其他字符将被跳过。例如,"bücher"被复制为 "bcher"。如果有任何字符被复制(即输入中至少有一个ASCII字符),则在输出中附加一个ASCII连字符(例如,"bücher"复制为"bcher-",其中"ü"不是ASCII字符,不发生复制)。

由于连字符本身是ASCII字符,因此可以出现在输入中,并将被复制到输出中。这并不会引起歧义,因为如果输出包含连字符,被添加的连字符总是最后一个,这标志着ASCII字符的结束。

编码非ASCII字符 编辑

对于输入的非ASCII字符,依Unicode中碼位由低至高順序,编码器会模擬將非ASCII字符一一插入回去除非ASCII字符後的字串過程, 计算每個非ASCII字符對應的三个数字inh

  • i 表示该非ASCII字符在输入字符串中的以0为开始索引的插入位置(类似于如C语言等的编程语言,用0来表示该非ASCII字符是输入字符串的第一个字符)。
  • n 表示该非ASCII字符在Unicode中的码位,减去127(127为最后一个ASCII字符)
  • h 表示該非ASCII字符插入時可能有的插入位置。如"ü"要插入回"bcher"中,可能有"übcher"到"bcherü"6個位置可供插入。

编码器随后计算乘法n*h+i并将得到的数字编码为一串36进制的可變長度數字,将这些数字转化为ASCII码,并将结果附加到输出字符串后。 每次計算後,該非ASCII字符會插入回去除非ASCII字符後的字串,因此h會增加1。 並且在計算下一個非ASCII字符Unicode碼位時,該碼位需減去上一個非ASCII字符碼位。

编码方式为:0 -> 'a', ..., 25 -> 'z', 26 -> '0', ..., 35 -> '9', 数字的数字按小端序排列。

此處的36进制的编码並非通常意義下的下36進制整數,而是一種可变长度的整数。每个数字的最重要(most significant)的位(例如数字 "123 "中的 "1")在没有上下文的情况下是可以识别的。因此,多个数字可以无需分隔地连接,不会影响原始数字的识别和提取。但此處每位數字進位的門檻閥值不同,並非每位皆是36進位。

用于国际化域名的ACE前缀 编辑

为了防止非国际域名中的连字符被Punycode解码,会在在国际化域名中的Punycode序列前加上字符串xn--。这被称为ACE(ASCII Compatible Encoding)。[2]

因此,域名"bücher.tld"将会以ASCII形式表示为"xn--bcher-kva.tld"。

解码器 编辑

解码器是具有两个状态变量in有限状态机

i是字符串的索引,范围从0(代表可能插入的开始)到扩展字符串的当前长度(代表可能插入的结束)。i从0开始。

n从128开始(128表示第一个非ASCII的码位)。

状态递增是一个单调函数。一个状态转移要么增加i,如果i达到最大,就重置i为零并增加n。下一个状态转移时,继续增加i。 在每个状态下,由n表示的码位要么被插入,要么不被插入。

编码器生成的数字代表在插入之前要跳过多少可能的结果。

在字符串 "bcher "中,有六个位置可以插入一个字符(包括第一个字符前和最后一个字符后)。在最后一个ASCII码位(127)和 "ü"(252,参见拉丁字母补充-1)之间有124个码位。有一个 "ü "的插入位置必须跳过(位置0,即在'b'之前)。

因此,在到达正确位置前,解码器将跳过共(6×124)+1=745个可能的插入位置。在该字符插入后,将有七个可能的地方插入下一个字符。

将码号重新编码为ASCII序列 编辑

Punycode使用通用变长整数来表示这些值。例如,"kva "将用来表示码号745。

小端序的数字系统允许不需要单独的分隔符的变长编码:低于阈值的数字标志着它是最重要的数字,即是数字的结束。为了提高效率,阈值取决于数字的位置和以前的插入。同时,数字的权重也会变化。

在使用36个符号的数字系统中,不区分大小写的'a'-'z'表示十进制数字0-25,'0'到'9'表示十进制数字26-35。因此,"kva",表示十进制数字序列"10 21 0"。

为了解码这串符号,需要阈值序列。本例中,阈值序列为(1,1,26,26,...)。[3]最不重要的数字(least-significant digit)的权重(或位置值)总是1,具有权重1的'k'等于10(1×10=10)。下一个数字的权重取决于第一个阈值:一般来说,对于任意n,第n+1个数字的权重是第n个数字的权重乘以(36-第n个数字的阈值)。所以第二个符号的权重是36减去前一个阈值,即为35(36-1=35)。因此,前两个符号'k'和'v'之和为10×1+21×35。由于第二个符号不小于其阈值1,因此还有更多符号。然而,由于本例中第三个符号是'a'(a=0),可以忽略其权重的计算。因此,"kva "代表十进制数字(10×1)+(21×35)=745。阈值本身由一个算法为每个编码字符序列决定,使其保持在1和26之间(包括1和26)。[4]字符的大小写可以用来提供关于原始字符串的大小写信息。[5]由于特殊字符按法编码算的码位排序,在插入"bücher"中特殊字符"ü"时,第一种可能是编码为 "bcher-kvaa "的 "büücher",第二种可能是编码为 "bcher-kvab "的 "bücüher",等等等等。在编码为 "bcher-kvae "的 "bücherü "之后是代表插入ý的编码,即ü之后的Unicode字符,从编码为 "bcher-kvaf "的 "ýbücher "开始(与编码为 "bcher-jvab "的 "übücher "不同),等等。

为了使编码、解码算法简单,编码时并没有试图阻止一些编码不允许的Unicode值:然而,解码时应该检查这些值。

Punycode的设计使其成可以在所有脚本中工作,并通过在操作过程中尝试适应字符串中的字符集范围进行自我优化。它针对字符串由包含0个或更多ASCII字符和来自其他脚本系统的字符组成的情况进行了优化,同时也能处理任意的Unicode字符串。在使用DNS时需要注意,域名字符串被认为已经使用nameprep英语nameprep进行了规范化处理,并且顶级域名在被punycode编码之前被假设已经根据官方注册的语言表进行了处理。同时,DNS协议对输出Punycode字符串的可接受长度也有所限制。

例子 编辑

下表展示了不同类型输入的国际化域名编码的例子。[6]

输入 输入的国际化域名编码 对输入的描述
空字符
a a- 仅有ASCII字符,一个小写字母
A A- 仅有ASCII字符,一个大写字母
3 3- 仅有ASCII字符,一个数字
- -- 仅有ASCII字符,一个连字符
-- --- 仅有ASCII字符,两个连字符
London London- 仅有ASCII字符,多于一个,没有连字符
Lloyd-Atkinson Lloyd-Atkinson- 仅有ASCII字符,一个连字符
This has spaces This has spaces- 仅有ASCII字符,包含空格
-> $1.00 <- -> $1.00 <-- 仅有ASCII字符,多种符号混合
а 80a 没有ASCII字符,一个西里尔字母
ü tda 没有ASCII字符,一个拉丁字母补充-1中的字符
α mxa 没有ASCII字符,一个希腊字母
fsq 没有ASCII字符,一个CJK字符
😉 n28h 没有ASCII字符,一个emoji字符
αβγ mxacd 没有ASCII字符,多于一个字符
München Mnchen-3ya 混合字符,包含一个非ASCII字符
Mnchen-3ya Mnchen-3ya- München的两次国际化域名编码
München-Ost Mnchen-Ost-9db 混合字符串,包括一个非ASCII字符和一个连字符
Bahnhof München-Ost Bahnhof Mnchen-Ost-u6b 混合字符串,包括一个空格,一个连字符和一个非ASCII字符
abæcdöef abcdef-qua4k 混合字符串,包括两个非ASCII字符
правда 80aafi6cg 俄语字符,不包括ASCII字符
ยจฆฟคฏข 22cdfh1b8fsa 泰语字符,不包括ASCII字符
도메인 hq1bm8jm9l 韩语字符,不包括ASCII字符
ドメイン名例 eckwd4c7cu47r2wf 日语字符,不包括ASCII字符
MajiでKoiする5秒前 nowrap|MajiKoi5-783gue6qz075azm5e 日语字符,以及ASCII字符
「bücher」 bcher-kva8445foa 混合的非ASCII字符(拉丁字母补充-1及CJK字符)

参考文献 编辑

  1. ^ . ICANN. [2019-01-22]. (原始内容存档于2022-05-16). 
  2. ^ Internet Assigned Numbers Authority. . www.atm.tut.fi. 2003-02-14 [2017-09-22]. (原始内容存档于2010-04-27). 
  3. ^ This is true for the first encoded character (or, in terms of RFC 3492, the first "delta"): see RFC 3492, Sec. 6.
  4. ^ RFC 3492, Secs. 3.4, 5.
  5. ^ RFC 3492, App. A.
  6. ^ The Punycode in this table was created using the builtin codec "punycode" of the Python programming language version 3.8 (s.encode("punycode")). See talk page.

国际化域名编码, 此條目可参照英語維基百科相應條目来扩充, 2016年12月, 若您熟悉来源语言和主题, 请协助参考外语维基百科扩充条目, 请勿直接提交机械翻译, 也不要翻译不可靠, 低品质内容, 依版权协议, 译文需在编辑摘要注明来源, 或于讨论页顶部标记, href, template, translated, page, html, title, template, translated, page, translated, page, 标签, 英語, punycode, 是一种表示unicode码和asci. 此條目可参照英語維基百科相應條目来扩充 2016年12月 若您熟悉来源语言和主题 请协助参考外语维基百科扩充条目 请勿直接提交机械翻译 也不要翻译不可靠 低品质内容 依版权协议 译文需在编辑摘要注明来源 或于讨论页顶部标记 a href Template Translated page html title Template Translated page Translated page a 标签 国际化域名编码 1 英語 Punycode 是一种表示Unicode码和ASCII码的有限的字符集 例如中文 上海 会被编码为 fhqz97e Punycode的目的是在于国际化域名标签 IDNA 的框架中 使这些 多语言 的域名可以编码为ASCII 编码语法在文档 RFC 3492 中规定 目录 1 编码过程 1 1 分离ASCII字符 1 2 编码非ASCII字符 1 3 用于国际化域名的ACE前缀 1 4 解码器 1 5 将码号重新编码为ASCII序列 2 例子 3 参考文献编码过程 编辑RFC 3492中说明 Punycode是一种称为Bootstring的更普遍的算法实例 它允许由部分基本的编码集合组成的字符串唯一表示由更大编码集合组成的任何字符串 配合Unicode文本的特性 Punycode定义了一般Bootstring算法的参数 本节以德语字符串 bucher 书籍 为例 演示Punycode的编码过程 该字符串被编码为 bcher kva 分离ASCII字符 编辑 首先 字符串中的所有ASCII字符将被直接从输入复制到输出 任何其他字符将被跳过 例如 bucher 被复制为 bcher 如果有任何字符被复制 即输入中至少有一个ASCII字符 则在输出中附加一个ASCII连字符 例如 bucher 复制为 bcher 其中 u 不是ASCII字符 不发生复制 由于连字符本身是ASCII字符 因此可以出现在输入中 并将被复制到输出中 这并不会引起歧义 因为如果输出包含连字符 被添加的连字符总是最后一个 这标志着ASCII字符的结束 编码非ASCII字符 编辑 对于输入的非ASCII字符 依Unicode中碼位由低至高順序 编码器会模擬將非ASCII字符一一插入回去除非ASCII字符後的字串過程 计算每個非ASCII字符對應的三个数字i n和h i 表示该非ASCII字符在输入字符串中的以0为开始索引的插入位置 类似于如C语言等的编程语言 用0来表示该非ASCII字符是输入字符串的第一个字符 n 表示该非ASCII字符在Unicode中的码位 减去127 127为最后一个ASCII字符 h 表示該非ASCII字符插入時可能有的插入位置 如 u 要插入回 bcher 中 可能有 ubcher 到 bcheru 6個位置可供插入 编码器随后计算乘法n h i并将得到的数字编码为一串36进制的可變長度數字 将这些数字转化为ASCII码 并将结果附加到输出字符串后 每次計算後 該非ASCII字符會插入回去除非ASCII字符後的字串 因此h會增加1 並且在計算下一個非ASCII字符Unicode碼位時 該碼位需減去上一個非ASCII字符碼位 编码方式为 0 gt a 25 gt z 26 gt 0 35 gt 9 数字的数字按小端序排列 此處的36进制的编码並非通常意義下的下36進制整數 而是一種可变长度的整数 每个数字的最重要 most significant 的位 例如数字 123 中的 1 在没有上下文的情况下是可以识别的 因此 多个数字可以无需分隔地连接 不会影响原始数字的识别和提取 但此處每位數字進位的門檻閥值不同 並非每位皆是36進位 用于国际化域名的ACE前缀 编辑 主条目 国际化域名 为了防止非国际域名中的连字符被Punycode解码 会在在国际化域名中的Punycode序列前加上字符串xn 这被称为ACE ASCII Compatible Encoding 2 因此 域名 bucher tld 将会以ASCII形式表示为 xn bcher kva tld 解码器 编辑 解码器是具有两个状态变量i和n的有限状态机 i是字符串的索引 范围从0 代表可能插入的开始 到扩展字符串的当前长度 代表可能插入的结束 i从0开始 n从128开始 128表示第一个非ASCII的码位 状态递增是一个单调函数 一个状态转移要么增加i 如果i达到最大 就重置i为零并增加n 下一个状态转移时 继续增加i 在每个状态下 由n表示的码位要么被插入 要么不被插入 编码器生成的数字代表在插入之前要跳过多少可能的结果 在字符串 bcher 中 有六个位置可以插入一个字符 包括第一个字符前和最后一个字符后 在最后一个ASCII码位 127 和 u 252 参见拉丁字母补充 1 之间有124个码位 有一个 u 的插入位置必须跳过 位置0 即在 b 之前 因此 在到达正确位置前 解码器将跳过共 6 124 1 745个可能的插入位置 在该字符插入后 将有七个可能的地方插入下一个字符 将码号重新编码为ASCII序列 编辑 Punycode使用通用变长整数来表示这些值 例如 kva 将用来表示码号745 小端序的数字系统允许不需要单独的分隔符的变长编码 低于阈值的数字标志着它是最重要的数字 即是数字的结束 为了提高效率 阈值取决于数字的位置和以前的插入 同时 数字的权重也会变化 在使用36个符号的数字系统中 不区分大小写的 a z 表示十进制数字0 25 0 到 9 表示十进制数字26 35 因此 kva 表示十进制数字序列 10 21 0 为了解码这串符号 需要阈值序列 本例中 阈值序列为 1 1 26 26 3 最不重要的数字 least significant digit 的权重 或位置值 总是1 具有权重1的 k 等于10 1 10 10 下一个数字的权重取决于第一个阈值 一般来说 对于任意n 第n 1个数字的权重是第n个数字的权重乘以 36 第n个数字的阈值 所以第二个符号的权重是36减去前一个阈值 即为35 36 1 35 因此 前两个符号 k 和 v 之和为10 1 21 35 由于第二个符号不小于其阈值1 因此还有更多符号 然而 由于本例中第三个符号是 a a 0 可以忽略其权重的计算 因此 kva 代表十进制数字 10 1 21 35 745 阈值本身由一个算法为每个编码字符序列决定 使其保持在1和26之间 包括1和26 4 字符的大小写可以用来提供关于原始字符串的大小写信息 5 由于特殊字符按法编码算的码位排序 在插入 bucher 中特殊字符 u 时 第一种可能是编码为 bcher kvaa 的 buucher 第二种可能是编码为 bcher kvab 的 bucuher 等等等等 在编码为 bcher kvae 的 bucheru 之后是代表插入y的编码 即u之后的Unicode字符 从编码为 bcher kvaf 的 ybucher 开始 与编码为 bcher jvab 的 ubucher 不同 等等 为了使编码 解码算法简单 编码时并没有试图阻止一些编码不允许的Unicode值 然而 解码时应该检查这些值 Punycode的设计使其成可以在所有脚本中工作 并通过在操作过程中尝试适应字符串中的字符集范围进行自我优化 它针对字符串由包含0个或更多ASCII字符和来自其他脚本系统的字符组成的情况进行了优化 同时也能处理任意的Unicode字符串 在使用DNS时需要注意 域名字符串被认为已经使用nameprep 英语 nameprep 进行了规范化处理 并且顶级域名在被punycode编码之前被假设已经根据官方注册的语言表进行了处理 同时 DNS协议对输出Punycode字符串的可接受长度也有所限制 例子 编辑下表展示了不同类型输入的国际化域名编码的例子 6 输入 输入的国际化域名编码 对输入的描述空字符a a 仅有ASCII字符 一个小写字母A A 仅有ASCII字符 一个大写字母3 3 仅有ASCII字符 一个数字 仅有ASCII字符 一个连字符 仅有ASCII字符 两个连字符London London 仅有ASCII字符 多于一个 没有连字符Lloyd Atkinson Lloyd Atkinson 仅有ASCII字符 一个连字符This has spaces This has spaces 仅有ASCII字符 包含空格 gt 1 00 lt gt 1 00 lt 仅有ASCII字符 多种符号混合a 80a 没有ASCII字符 一个西里尔字母u tda 没有ASCII字符 一个拉丁字母补充 1中的字符a mxa 没有ASCII字符 一个希腊字母例 fsq 没有ASCII字符 一个CJK字符 n28h 没有ASCII字符 一个emoji字符abg mxacd 没有ASCII字符 多于一个字符Munchen Mnchen 3ya 混合字符 包含一个非ASCII字符Mnchen 3ya Mnchen 3ya Munchen的两次国际化域名编码Munchen Ost Mnchen Ost 9db 混合字符串 包括一个非ASCII字符和一个连字符Bahnhof Munchen Ost Bahnhof Mnchen Ost u6b 混合字符串 包括一个空格 一个连字符和一个非ASCII字符abaecdoef abcdef qua4k 混合字符串 包括两个非ASCII字符pravda 80aafi6cg 俄语字符 不包括ASCII字符yckhfkhtkh 22cdfh1b8fsa 泰语字符 不包括ASCII字符도메인 hq1bm8jm9l 韩语字符 不包括ASCII字符ドメイン名例 eckwd4c7cu47r2wf 日语字符 不包括ASCII字符MajiでKoiする5秒前 nowrap MajiKoi5 783gue6qz075azm5e 日语字符 以及ASCII字符 bucher bcher kva8445foa 混合的非ASCII字符 拉丁字母补充 1及CJK字符 参考文献 编辑 国际化域名 词汇表 ICANN 2019 01 22 原始内容存档于2022 05 16 Internet Assigned Numbers Authority Completion of IANA Selection of IDNA Prefix www atm tut fi 2003 02 14 2017 09 22 原始内容存档于2010 04 27 This is true for the first encoded character or in terms of RFC 3492 the first delta see RFC 3492 Sec 6 RFC 3492 Secs 3 4 5 RFC 3492 App A The Punycode in this table was created using the builtin codec punycode of the Python programming language version 3 8 s encode punycode See talk page 取自 https zh wikipedia org w index php title 国际化域名编码 amp oldid 74614089, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。