UTF-8需要4个字节来表示BMP之外的字符。那不是坏;它不比UTF-16或UTF-32差。但它并不是最佳的(就存储空间而言)。
从未使用过13个字节(C0-C1和F5-FF)。和未使用的多字节序列,例如对应于“过长”编码的序列。如果这些字符可用于编码,那么它们中的更多可能由2字节或3字节序列表示(当然,代价是使实现更复杂)。
是否可以通过类似UTF-8的编码表示所有1,114,112个Unicode代码点,每个字符最多3个字节?如果没有,这样的编码可以代表的最大字符数是多少?
“UTF-8-like”,我的意思是,至少:
find
/ index
函数正常工作。你不能像在Shift-JIS中那样从一个角色的中间开始找到误报。更新 - 我第一次尝试回答问题
假设您具有前导/尾随字节的UTF-8样式分类。让:
然后可以支持的字符数是N = A + BT +CT²。
给定A = 128,最佳值为B = 0且C = 43.这允许310,803个字符,或大约28%的Unicode代码空间。
是否有可以编码更多字符的不同方法?
答案 0 :(得分:4)
记录所有Unicode代码点需要20多位(假设你的数字是正确的),从24位中留下超过3位用于编码哪个字节是哪个。这应该足够了。
与没有达到既定标准的情况相比,我没有看到你会从中获得什么。
编辑:再次读取规范,您希望为前128个代码点保留值0x00到0x7f。这意味着您只有3个字节的21位来编码剩余的1,113,984个代码点。 21位勉强够用,但它并没有给你足够的额外信息来明确地进行编码。或者至少我还没想出办法,所以我改变了我的答案。
至于你的动机,好奇和参与一些思考练习肯定没什么不对。但思考练习的目的是自己,而不是试图让整个互联网为你做到这一点!在提问时,至少要提前做好准备。
答案 1 :(得分:2)
我做了数学计算,但这是不可能的(如果想要严格保持“UTF-8-like”)。
首先,UTF-8的四字节范围涵盖U+010000 to U+10FFFF
,这是可用字符的一大部分。这就是我们尝试仅使用3个字节替换的内容。
通过特殊套管你提到的13个未使用的前缀字节中的每一个,你可以获得65,536个字符,这使我们总共13 * 0x10000
或0xD0000
。
这会使总3字节字符范围变为U+010000 to U+0DFFFF
,几乎全部,但还不够。
答案 2 :(得分:1)
当然有可能。证明:
2 24 = 16,777,216
因此,1,114,112个字符有足够的位空间,但位空间越拥挤,每个字符使用的位越多。 UTF-8的重点在于它假设较低的代码点在字符流中更有可能,因此即使某些字符可能使用4个字节,整个事物也会非常有效。
假设0-127仍然是一个字节。这为1.1M字符留下了8.4M空间。然后你可以解决这个问题。选择一种编码方案,其中第一个字节确定使用的字节数。所以有128个值。其中每个代表256个字符(总共2个字节)或65,536个字符(总共3个字节)。所以:
256x + 65536(128-x)= 1114112 - 128
解决这个问题,您需要将第一个字节的111个值作为2个字节的字符,将剩余的17个值作为3个字节。检查:
128 + 111 * 256 + 17 * 65536 = 1,114,256
换句话说:
当然,这不允许UTF-8不可避免地扩展Unicode。您可以将其调整为第一个字节,意思是:
这样会更好,因为它是简单的按位AND测试来确定长度并提供4,210,816个代码点的地址空间。