为什么有些IDN不可逆:
String domain = "aʼnċăwb7rňuħ.eu";
System.out.println(domain);
domain = IDN.toASCII(domain);
System.out.println(domain);
domain = IDN.toUnicode(domain);
System.out.println(domain);
显示:
aʼnċăwb7rňuħ.eu
xn--anwb7ru-93a5e8ozmq2m.eu
aʼnċăwb7rňuħ.eu
如您所见,第二个角色已被拆分!
由于
答案 0 :(得分:2)
这是设计的。据我所知,字符串中的第二个字符是\ u0149代码点。根据最新的Unicode代码图表:
此字符已弃用且已被使用 强烈劝阻
Unicode代码表显示已弃用的代码点等同于\u02bc
,后跟\u006e
。
根据javadocs,IDN.toASCII(String)
所做的第一步是使用RFC 3491 stringprep / nameprep算法来处理输入字符串中的字符。 RFC摘要说:
本文档介绍了如何准备国际化域名 (IDN)标签以增加名称输入的可能性 名称比较以对典型用户有意义的方式工作 遍及世界。这个stringprep协议的配置文件是 用作一套在线协议的一部分 国际化域名系统(DNS)。
(换句话说,stringprep旨在使创建看起来像一件事并且意味着不同的棘手域名变得更加困难。)
实际上,如果向下钻取,您会发现\u0149
的stringprep表中的指定映射为\u02bc
\u006e
;即Unicode代码图表中定义的等价物。
而且......这就是正在发生的事情。
<强>摘要强>
答案 1 :(得分:0)
IDN toASCII程序本质上不可逆,因为它涉及执行Unicode规范化(形成NFKC)作为过程的一部分。通常,多个Unicode字符序列可以具有相同的规范化形式; IDN toUnicode过程将从ACE标签中生成一个这些表单,但不能保证它与最初编码的那个相同。
如果toUnicode(toASCII(x))
的结果确实与x
不同,那么这两者在IDN的目的上是等效的,并且它们还应该是彼此的Unicode兼容性等价物。一般来说,Unicode字体将以类似方式呈现它们。从这个意义上说,你的情况有一个显着的差异有点令人惊讶,但最重要的是,你对可逆性的明显期望是没有根据的。