是否存在使用utf-8中所有可用且可打印的合法字符的二进制数据的标准化编码?

时间:2015-09-23 09:16:06

标签: mysql utf-8 base64

我的意思是将它放在VARCHAR列中进行utf8_bin整理。 base64的结果是生成的文本比原始文本长,第二个问题是我正确理解 this question mysql限制varchar的字符数不是真正的字节大小,因为utf-8编码的文本可以有超过3个字节的字符,这可能会限制命中列边界的可能性。

生成的utf-8文本应该像乱码中文或mojibake,如下所示:Twitter image encoding challenge

但我的问题恰恰在于是否存在某种“标准化”算法,因此我不必重新发明轮子。

2 个答案:

答案 0 :(得分:2)

实用算法在很大程度上取决于某个数据存储的UTF-8实现如何清理输入字符串。

  • 是否允许“超长”字节序列?
  • 是否允许代理?
  • 代码点是否限制为Unicode最大值0x10FFFF?
  • 是否允许所有ASCII控制字符?
  • 是否禁止使用其他任何Unicode字符?

假设只检查0x10FFFF最大值,您会得到一定长度的UTF-8字节序列的以下结果:

1字节序列

最大代码点:0x7F
位/代码点:7
bits / byte:7

2字节序列

最大代码点:0x7FF
位/代码点:11
位/字节:5.5

3字节序列

最大代码点:0xFFFF
位/代码点:16
位/字节:5.33

4字节序列

最大代码点:0x10FFFF
位/代码点:~20
位/字节:〜5

如果数据存储限制了存储的字节数,您显然希望将数据存储为ASCII,以最大化二进制输入数据的数量。

更有趣的情况是数据存储限制了Unicode“字符”的数量(实际上是代码点)。这里最好使用4字节UTF-8序列。许多数据存储接受从0x10000到0x10FFFF的所有代码点,这允许每个代码点存储20位(2.5字节)的二进制数据。

如果可用代码点的数量不是2的幂,则基本上必须将输入分解为基数n(n~1,000,000)以获得最佳编码。

答案 1 :(得分:1)

所有有效的4字节UTF-8序列(或更短的)都可以存储在MySQL CHARACTER SET utf8mb4中。

CHAR(10) CHARACTER SET utf8占用30个字节(每个字符3个字节) CHAR(10) CHARACTER SET utf8mb4占用40个字节 VARCHAR(NN) CHARACTER SET XX占用长度为1或2个字节,加上最多NN个字符集所需的字节数。

虽然utf8编码标准(和Unicode)允许超过4个字节,但尚未建立此类字符。 (并且MySQL还无法处理它们。)所以,我认为utf8mb4处理&ut;来自utf-8"的所有可用和可打印的合法字符。

"整理"是指比较和排序顺序,而不是编码或存储。

当右手不知道左手有什么时,就会出现Mojibake和其他一些乱语。也就是说,当客户端和服务器之间的切换期间CHARACTER SET不匹配时。

VARBINARY的使用正在席卷地毯下的真正的问题。