我要求计算 Unicode 中所有可能的有效组合并附上解释。
1,111,998:17 个平面 × 每个平面 65,536 个字符 - 2048 个代理项 - 66 个非字符
请注意,UTF-8 和 UTF-32 理论上可以编码超过 17 个平面,但范围基于 limitations of the UTF-16 encoding 受到限制。
137,929 个代码点实际上是在 Unicode 12.1 中分配的。
我也不明白为什么连续字节有限制,即使那个字符的起始字节清除了它应该有多长。
UTF-8 中此限制的目的是使编码为 self-synchronizing。
举个反例,考虑中文的GB 18030 encoding。在那里,字母 ß
表示为字节序列 81 30 89 38
,其中包含数字 0
和 8
的编码。因此,如果您的字符串搜索功能不是针对这种特定于编码的怪癖而设计的,那么对数字 8
的搜索将在字母 ß
中发现误报。
在 UTF-8 中,这不会发生,因为前导字节和尾随字节之间的不重叠保证了较短字符的编码永远不会发生在较长字符的编码中。
Unicode 允许 17 个 planes,每个字符有 65,536 个可能的字符(或“代码点”)。这给出了总共 1,114,112 个可能的字符。目前,仅分配了大约 10% 的空间。
这些代码点如何编码的确切细节与编码不同,但您的问题听起来像是您在考虑 UTF-8。限制连续字节的原因大概是这样很容易找到下一个字符的开头(因为连续字符总是采用 10xxxxxx 的形式,但起始字节永远不会是这种形式)。
Unicode 支持 1,114,112 个代码点。有 2048 个代理代码点,给出 1,112,064 个标量值。其中,有 66 个非字符,导致 1,111,998 个可能的编码字符(除非我计算错误)。
为了给出一个隐喻准确的答案,all of them
。
UTF-8 编码中的连续字节允许在面对“线路噪声”时重新同步编码的八位字节流。编码器只需要向前扫描一个在 0x80 和 0xBF 之间没有值的字节,就知道下一个字节是新字符点的开始。
从理论上讲,今天使用的编码允许表达 Unicode 字符数最多为 31 位的字符。实际上,这种编码实际上是在 Twitter 等服务上实现的,其中最大长度的推文可以编码多达 4,340 位的数据。 (140 个字符 [有效和无效],每个乘以 31 位。)
perl -le 'print ord "\x{1FFF_FFFF_FFFF}"'
在 64 位机器上打印出 35184372088831,但在 32 位机器上给出整数溢出。您可以在 perl 程序中使用更大的字符,但如果您尝试将它们打印为 utf8,则会收到强制警告,除非您禁用此类:perl -le 'print "\x{1FFF_FFFF}"' Code point 0x1FFFFFFF is not Unicode, may not be portable at -e line 1. ######
。 “宽松的utf8”和“严格的UTF-8”是有区别的:前者不受限制。
len(chr(0x10000))
,给出 2(代码单元)。 OS X 的内核使用 UTF-8,没错,但高级 API(Cocoa 等)使用 UTF-16。
[𝒜-𝒵]
,您就会明白为什么我发现暴露 UTF-16 是一个烂问题。让程序员思考编码形式而不是逻辑字符是错误的。
Unicode 的十六进制数是 110000,即 1114112
根据 Wikipedia,Unicode 12.1(2019 年 5 月发布)包含 137,994 个不同的字符。