据我了解,非静态结构的随意二进制序列化实现(例如数组或向量)通常会陈述结构的"长度",因为em>(通常是64位UINT),然后继续编码每个实体的值,而无需分离器(给定数组的每个单元格中的序列化主题数据都是确定性的,因此二进制解析器不需要任何lookahead或backtracking)。
对于UTF-8字符串而言,这种行为会相同吗?我看不到任何其他方法来实现"无界" UTF-8字符串的二进制序列化,因此解析器不需要回溯(实际上可能是效率低下)或lookahead(这也需要针对各种可能性进行过多的测试,也效率低下)。我的猜测是,"长度"值表示字符的数量,而不是字节数,因为UTF-8编码每个字符的编码范围为1到4个字节,尽管编码本身表示字符中存在多少个字节基于第一个字节(消除回溯和lookahead,per-tharacter)。
作为一个例子,字符串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,就可以使用无效的byte字符串。否则,也可以按照您在问题中显示的前面长度使用。
例如,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不需要回溯或lookahead,因为序列的铅字节表示代码点所需的尾随字节数:
61 hex = 0 1100001 bin (单字节序列)
C3 hex = 110 00011 bin (两字节序列)
e4 hex = 1110 0100 bin (三字节序列)
尾随字节全部以 10 xxxxxxx bin :
a9 hex = 10 101001
bin (tarring byte)
B8 hex = 10 111000 bin (tailting byte)
80 hex = 10 000000 bin (tailting byte)