【问题标题】:What are surrogate characters in UTF-8?UTF-8 中的代理字符是什么?
【发布时间】:2018-12-02 17:04:33
【问题描述】:

我有一个奇怪的验证程序,可以验证 utf-8 字符串是否是有效的主机名(PHP 中的 Zend Framework Hostname valdiator)。它允许 IDN(国际化域名)。它将每个子域与由其 HEX 字节表示定义的字符集进行比较。两个这样的集合是D800-DB7FDC00-DFFF。在这些比较过程中,名为 preg_match 的 PHP 正则表达式比较函数失败,并且表示此函数中不允许使用 DC00-DFFF 字符。从维基百科我了解到这些字节在 UTF-8 中被称为代理字符。 thay 是什么以及它们实际对应的字符是什么?我在几个地方读过,我仍然不明白它们是什么。

【问题讨论】:

  • 在 UTF-16 中使用代理代码点来表示 FFFF 之外的代码点。它们成对使用,因此一个字符由 4 个字节组成。 UTF-8 不需要这种机制,因此用 UTF-8 编码的文本不应包含它们。但是,可以使用 UTF-8 对代理代码点进行编码,因此验证例程识别它们是有意义的。
  • @lenz 我可以说DC00-DFFF 中的字符不是有效的UTF-8 字符吗?是这样吗?它们可以出现在域名中吗?
  • Err... 我知道他们不应该在那里,但我不能告诉你违反了哪个标准,如果他们违反了有多严重。域名我也不知道,抱歉。

标签: utf-8 utf surrogate-pairs


【解决方案1】:

UTF-8 中的代理字符是什么?

这几乎就像一个技巧问题。

近似答案 #1:4 个字节(如果配对并以 UTF-8 编码)。

近似答案 #2:无效(如果未配对)。

近似答案 #3:不是 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 您可以将 UTF-8 编码算法应用于无效的代码点,这是无效的。它们无法解码为有效的代码点。兼容的阅读器会抛出异常或丢弃字节并插入替换字符 (�)。

#3 Java 提供了一种使用称为 JNI 的系统在外部代码中实现功能的方法。 Java String API 提供对 String 和 char 作为 UTF-16 代码单元的访问。在 JNI 的某些地方,可能是为了方便,字符串值是修改后的 UTF-8。修改后的 UTF-8 是应用于 UTF-16 代码单元而不是 Unicode 代码点的 UTF-8 编码算法。

无论如何,字符编码的基本规则是使用用于写入的编码进行读取。如果要将任何字节序列视为文本,则必须知道编码;否则,您会丢失数据。

【讨论】:

    猜你喜欢
    • 2015-06-23
    • 2012-03-25
    • 2013-06-12
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    相关资源
    最近更新 更多