UTF-8可表示1112064个字符的正确计算逻辑是什么?
UTF-8 1112064个可表示字符的计算逻辑
1112064这个数值和是否排除Emoji没有任何关系,你算出2164864的核心偏差是:只按编码长度的有效位算出了UTF-8的理论最大编码容量,没有扣除规范里明确禁止的非法编码值。
UTF-8除了每个长度的固定前缀、有效位数量要求外,还有三个强制合法性约束,违反约束的编码都是无效的,不能用来映射字符:
- 禁止过长编码:同一个码点必须用最短的合法字节长度表示,比如ASCII字符如果编成2/3/4字节长度就属于非法
- 禁止编码UTF-16代理对区间码位:
U+D800~U+DFFF是Unicode预留给UTF-16代理对的永久保留位,永远不会分配字符,UTF-8不允许编码这部分值 - 禁止编码超过Unicode上限的值:Unicode定义的最大合法码点为
U+10FFFF,超过这个值的编码全为非法
逐段计算合法编码数量
按编码长度分别统计合法值,最后求和就能得到1112064的结果:
- 1字节编码:有效位7位,对应码点范围
U+0000~U+007F,共2^7=128个,全部合法,无需要扣除的值。 - 2字节编码:有效位共11位,理论容量
2^11=2048。这里需要扣除128个过长编码(对应U+0000`U+007F`,这部分本该用1字节表示),最终合法数量为`2048-128=1920`,对应码点范围`U+0080`U+07FF。 - 3字节编码:有效位共16位,理论容量
2^16=65536。这里需要扣除两部分非法值:一是2048个过长编码(对应U+0000`U+07FF`,本该用1/2字节表示),二是2048个代理对保留码位(`U+D800`U+DFFF),最终合法数量为65536-2048-2048=61440,对应码点范围U+0800~U+FFFF(剔除代理对区间)。 - 4字节编码:有效位共21位,理论容量
2^21=2097152。这里需要扣除两部分非法值:一是65536个过长编码(对应U+0000`U+FFFF`,本该用1/2/3字节表示),二是983040个超过Unicode最大码点`U+10FFFF`的无效值,最终合法数量为`2097152-65536-983040=1048576`,对应码点范围`U+10000`U+10FFFF。
最终求和
把四个长度的合法编码数加总:128 + 1920 + 61440 + 1048576 = 1112064
关于Emoji的补充说明
这个数值是严格符合规范的UTF-8能表示的所有Unicode码点总数,和是否排除Emoji无关。目前已分配的Emoji全部位于合法码点区间内(绝大多数在4字节编码的U+1F000及以上区段),本身就被包含在1112064的统计范围内。这个数字既不区分码点是否已经分配字符,也不区分字符类型是文字、符号还是Emoji。
内容的提问来源于stack exchange,提问作者Hasnat Pie
相关产品推荐
相关产品推荐

