Unicode编码点限制

16

正如这里所解释的那样,所有Unicode编码都以最大代码点10FFFF结束,但我听说它们可以延伸到6个字节,这是真的吗?

4个回答

8

在其发展过程中,UTF-8经历了一些变化,并有许多规范(现在大部分已经过时)对UTF-8进行了标准化。这些变化大多是为了增强与UTF-16的兼容性以及允许更多的代码点。

简而言之,UTF-8最初被指定为允许最高31位(或6个字节)的代码点。但是,随着RFC3629的出现,最大长度缩短至4个字节以增强与UTF-16的兼容性。

维基百科上有更多信息。通用字符集规范与Unicode及其转换格式(UTF)的历史密切相关。


2
@Ted:就像我说的那样,一切都取决于你认为 UTF-8 是什么,因为存在不同(部分已过时)的标准。其中最新的一个是 RFC 3692。此外,请注意 UTF 不等于 UCS。UTF-8 只为在 UCS 中定义的字符定义了编码标准(因此 ISO 10646-1)。 - Holger Just
@Holger:“最新的是RFC 3692” -> RFC 3629,不是3692(你在第一篇帖子中是正确的)。 - Hibou57
1
@Hibou57:这只是一个测试 :) 当然,你是正确的。 - Holger Just
utf-8 机制允许最多 8 字节的序列。即使是 7 字节的序列,在起始字节中也没有任何有效载荷位,而 8 字节序列的起始字节也没有任何有效载荷位。但是,7 字节序列会导致以下字节的 6 x 6 = 36 个有效载荷位,而 8 字节序列会导致以下字节的 7 x 6 = 42 个有效载荷位。但由于 0x10ffff Unicode 代码点限制,utf-8 最多只允许 4 字节序列。 - brighty

4

对的。utf-8和utf-32的限制不仅在于最高代码点的限制,而且还不能编码代理项,并且对于utf-8,始终要使用最短的序列。 - brighty

3
最大的Unicode码点和使用的Unicode字符编码是两件事情。根据标准,最高的码点实际上是0x10ffff,但你只需要21位即可,这很容易适配到4个字节中,即使浪费了11位!
我猜你关于6个字节的问题指的是6个字节的UTF-8序列,对吗?正如其他人已经回答的那样,使用UTF-8机制,你确实可以处理6个字节序列,甚至可以处理7个字节序列和8个字节序列。7个字节序列给你提供了以下字节要提供的范围,6×6位=36位,而8个字节序列给你提供了7×6位=42位。你可以处理它,但不允许,因为最高的码点是0x10ffff。
正如Hibou57所提到的,也禁止使用比必需更长的序列。使用UTF-8时,必须始终使用最短的序列,否则该序列将被视为无效!ASCII字符当然必须在一个7位单字节中。第二件事是,UTF-8的4个字节序列在起始字节中给出3个有效负载位,在以下字节中给出18个有效负载位,共计21位,这与在使用UTF-16编码时计算代理项的计算相匹配。从码点中减去偏移量0x10000,剩下的20位进入高代理区域和低代理有效负载区域,每个有效负载10位。第三件也是最后一件事是,在UTF-8中不允许编码高或低代理值。代理项不是字符而是容器,只能出现在UTF-16中,不能在UTF-8或UTF-32编码的文件中出现。

1

实际上,对于UTF-8编码的某些视图,UTF-8技术上允许编码超出永久固定有效范围上限的代码点;因此,您可以编码超出该范围的代码点,但它将不是任何地方的有效代码点。另一方面,您可以使用不需要的零高位比特编码字符,例如使用Ada符号表示的多个比特编码ASCII代码点,如2#1100_0001#,2#1000_0001#,这将使ASCII字母A UTF-8编码为两个字节。但是,它可能会被某些安全过滤器拒绝,因为这种方法常用于黑客和盗版。RFC 3629对此进行了一些解释。应该只编码有效的代码点(由Unicode定义),以安全的方式(没有多余的字节)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接