是否可以将类似UTF-8的编码限制为每个字符3个字节?

时间:2010-06-10 02:32:08

标签: unicode utf-8 character-encoding

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”,我的意思是,至少:

  • 字节0x00-0x7F保留用于ASCII字符。
  • 面向字节的find / index函数正常工作。你不能像在Shift-JIS中那样从一个角色的中间开始找到误报。

更新 - 我第一次尝试回答问题

假设您具有前导/尾随字节的UTF-8样式分类。让:

  • A =单字节字符数
  • B =用于引导2字节字符字节的值的数量
  • C =用于3字节字符的前导字节的值的数量
  • T = 256 - (A + B + C)=用于尾随字节的值的数量

然后可以支持的字符数是N = A + BT +CT²。

给定A = 128,最佳值为B = 0且C = 43.这允许310,803个字符,或大约28%的Unicode代码空间。

是否有可以编码更多字符的不同方法?

3 个答案:

答案 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 * 0x100000xD0000

这会使总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

换句话说:

  • 128个代码点需要1个字节;
  • 28,416个代码点需要2个字节;和
  • 1,114,112个代码点需要3个字节。

当然,这不允许UTF-8不可避免地扩展Unicode。您可以将其调整为第一个字节,意思是:

  • 0-127(128)= 1字节;
  • 128-191(64)= 2字节;
  • 192-255(64)= 3个字节。

这样会更好,因为它是简单的按位AND测试来确定长度并提供4,210,816个代码点的地址空间。