Serialization utf-8编码是否需要字符长度?

Serialization utf-8编码是否需要字符长度?,serialization,utf-8,string-length,variable-length,Serialization,Utf 8,String Length,Variable Length,据我所知,非静态结构(如数组或向量)的偶然二进制序列化实现通常将结构的“长度”表示为第一个字(通常为64位uint),然后继续编码每个实体的值,而不使用分隔符(假设数组的每个单元格中的序列化主题数据都是确定性的,因此二进制解析器不需要任何前瞻或回溯) 传统上,utf-8字符串的这种行为会是相同的吗?我看不到任何其他方法可以实现“无界”utf-8字符串的二进制序列化,这样解析器就不需要回溯(这可能非常低效)或前瞻(这也需要针对各种可能性进行过度测试,效率也很低)。我猜“长度”值将表示字符数,而不是

据我所知,非静态结构(如数组或向量)的偶然二进制序列化实现通常将结构的“长度”表示为第一个字(通常为64位uint),然后继续编码每个实体的值,而不使用分隔符(假设数组的每个单元格中的序列化主题数据都是确定性的,因此二进制解析器不需要任何前瞻或回溯)

传统上,utf-8字符串的这种行为会是相同的吗?我看不到任何其他方法可以实现“无界”utf-8字符串的二进制序列化,这样解析器就不需要回溯(这可能非常低效)或前瞻(这也需要针对各种可能性进行过度测试,效率也很低)。我猜“长度”值将表示字符数,而不是字节数,因为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,就可以使用以null结尾的字节字符串,而不使用前置长度;否则,也可以使用前置长度,如您在问题中所示

例如,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(单字节序列)
c3hex=11000011bin(两字节序列)
e4hex=11100100bin(三字节序列)

尾随字节均以10xxxxxx bin开头:

a9hex=10101001bin(尾随字节)
b8hex=10111000bin(尾随字节)
80hex=10000000字节(尾随字节)


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

例如,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(单字节序列)
c3hex=11000011bin(两字节序列)
e4hex=11100100bin(三字节序列)

尾随字节均以10xxxxxx bin开头:

a9hex=10101001bin(尾随字节)
b8hex=10111000bin(尾随字节)
80hex=10000000字节(尾随字节)


我不明白您想要实现什么。UTF-8是一种二进制编码,因此您应该将UTF-8视为字节的二进制序列。如果您想要有语义值,您应该使用Unicode代码点(因此UTF-8已解码)。我认为将语义与二进制表示混合会带来一些麻烦。为了提高效率,您可以查看python:它查看更高的代码点,然后确定编码是扩展ASCII还是16位整数数组(UTF-16排序)还是32位整数数组(UTF-32排序)@GiacomoCatenazzi我知道,如果我的二进制字符串被假定为完全是utf-8编码的文本数据,那么我不需要提供一个范围,只需要解析到穷尽,但在某些utf-8数据可能是结构的字段的过程中,例如,我相信需要一个范围参数,我将其作为第一个单词指示。I我只是想知道大多数语言通常是如何做到这一点的。大多数语言都不使用编码的Unicode。Python、Javascript(以及在windows上的某些扩展C)通常在内部使用UCS-2。一些语言(如通常的C)它就像以零结尾的二进制字符串一样使用它。我真的会避免混合编码和语义。在这种情况下,你应该解析字符串并检查它是否有效,并处理无效的情况[因此你几乎有解码器,它会丢弃结果]注:字节长度是唯一的,关于unicode长度,有多种解释:代码点的数量或“可打印字符”的数量(重音字母的长度为1)。已知包含用UTF-8编码的文本的字节数组是一个不变的概念。它可以像任何其他字节数组一样处理。字符串和UTF-8字符串的概念在编程语言中并不普遍。简言之,如果需要,请使用字节计数。我不明白您试图实现什么。UTF-8是一种二进制编码,所以您应该将UTF-8视为字节的二进制序列。如果您希望具有语义值,则应使用Unicode代码点(因此UTF-8已解码)。我认为将语义与二进制表示混合会带来一些麻烦。为了提高效率,您可以查看python:它查看更高的代码点,然后确定编码是扩展ASCII还是16位整数数组(UTF-16排序)还是32位整数数组(UTF-32排序)@GiacomoCatenazzi我理解,如果我的二进制字符串被假定为完全是utf-8编码的文本数据,那么我不需要提供