utf-8编码需要字符长度吗?

Does utf-8 encoding need character length?

据我所知,非静态结构(如数组或向量)的随意二进制序列化实现通常会将结构的 "length" 声明为 第一个词(通常是 64 位 uint),然后继续对每个实体的值进行编码,不带分隔符(假定数组每个单元格中的序列化主题数据是确定性的,因此二进制解析器不需要任何前瞻或回溯)。

传统上,对于 utf-8 字符串,这种行为是否相同?我看不到为 "unbounded" utf-8 字符串实现二进制序列化的任何其他方法,这样解析器就不需要回溯(这可能真的很低效)或前瞻(这也需要针对各种可能性,也是低效的)。我的猜测是 "length" 值表示字符数,而不是字节数,因为 utf-8 编码范围为每个字符 1 到 4 个字节,尽管编码本身表示有多少字节存在于基于第一个字节的字符(消除回溯和前瞻,每个字符)。

例如,字符串 abc 的八位字节流将是

[0,0,0,0,0,0,0,3,97,98,99]

其中0,0,0,0,0,0,0,3表示输入字符串的uint64长度,abc.

我的直觉是正确的,还是我遗漏了什么?

在 UTF-8 中,Unicode 代码点 U+0000 (NUL) 被编码为值为零的单个字节。它不会出现在 UTF-8 中任何其他代码点的编码中,因此只要序列中不允许嵌入 NUL,就可以使用没有前导长度的空终止字节字符串;否则,也可以使用前面的长度,如您在问题中所示。

例如,Unicode 字符串 "abcdéfg一二三四" 编码为十六进制字节:

61 62 63 64 c3 a9 66 67 e4 b8 80 e4 ba 8c e4 b8 89 e5 9b 9b 00
a  b  c  d  é     f  g  一       二       三       四        ␀

UTF-8 不需要回溯或前瞻,因为序列的前导字节指示代码点所需的尾随字节数:

61hex = 01100001bin (one-byte sequence)
c3hex = 11000011bin (two-byte sequence)
e4hex = 11100100bin (three-byte sequence)

尾随字节全部以10xxxxxxbin:

开头

a9hex = 10101001bin (trailing byte)
b8hex = 10111000bin (trailing byte)
80hex = 10000000bin (trailing byte)