我有一个奇怪的验证程序,用于验证 utf-8 字符串是否是有效的主机名(PHP 中的 Zend Framework Hostname valdiator)。它允许 IDN(国际化域名)。它将每个子域与由其十六进制字节表示定义的字符集进行比较。两个这样的集合是D800-DB7F
and DC00-DFFF
。 PHP正则表达式比较函数调用preg_match
在这些比较期间失败,它说DC00-DFFF
此函数中不允许使用字符。从维基百科我了解到这些字节在 UTF-8 中被称为代理字符。它们是什么以及它们实际上对应于哪些字符?我读了好几个地方,但还是不明白它们是什么。
UTF-8 中的代理字符是什么?
这几乎就像一个技巧问题。
近似答案#1:4 个字节(如果配对并以 UTF-8 编码)。
近似答案#2:无效(如果未配对)。
近似答案#3:它不是 UTF-8;它不是 UTF-8。它是修改后的UTF-8.
概要:该术语不适用于 UTF-8。
Unicode 代码点的范围需要 21 位数据。
UTF-16 代码单元为 16 位。 UTF-16 将某些范围的 Unicode 代码点编码为一个代码单元,将其他代码点编码为两个代码单元对,第一个来自“高”范围,第二个来自“低”范围。 Unicode 将与高低对范围匹配的代码点保留为无效。他们有时被称为代理人,但他们不是角色。它们本身没有任何意义。
UTF-8 代码单元是 8 位。 UTF-8 分别以一到四个代码单元对几个不同范围的代码点进行编码。
#1 碰巧 UTF-16 使用两个 16 位代码单元编码的代码点,UTF-8 使用 4 个 8 位代码单元编码,反之亦然。
#2 可以对无效的codepoint应用UTF-8编码算法,即无效。它们无法解码为有效的代码点。兼容的读取器会抛出异常或抛出字节并插入替换字符 (�)。
#3 Java 提供了一种通过称为 JNI 的系统在外部代码中实现功能的方法。 Java String API 提供对 String 和 char 作为 UTF-16 代码单元的访问。在 JNI 的某些地方,可能是为了方便起见,字符串值是修改后的UTF-8。 Modified UTF-8 是应用于 UTF-16 代码单元而不是 Unicode 代码点的 UTF-8 编码算法。
无论如何,字符编码的基本规则是使用用于写入的编码进行读取。如果要将任何字节序列视为文本,则必须知道编码;否则,您会丢失数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)