什么是UTF-8数据的良好终止字节?

8
我需要在低级环境中操作UTF-8字节数组。这些字符串将具有相似的前缀,并保存在利用此特性的容器中(即trie)。为尽可能地保持这种前缀相似性,我更喜欢在我的字节数组末尾使用终止符,而不是(例如)字节长度前缀。
我应该使用什么终止符?看起来0xff在任何UTF-8字符串的所有位置上都是非法的字节,但也许有人确切知道吗?
3个回答

6

0xFF0xFE在合法的UTF-8数据中不会出现。此外,字节0xF8-0xFD只会出现在已过时的UTF-8版本中,该版本允许多达六个字节序列。

0x00是合法的,但除了U+0000的编码之外,不会出现在任何地方。这与其他编码完全相同,事实上它在所有这些编码中都是合法的,但这并没有阻止它被用作C字符串中的终止符号。我可能会选择0x00


6

字节0xff不能出现在有效的UTF-8序列中,也不能出现任何0xfc、0xfd、0xfe。

所有UTF-8字节必须匹配以下其中之一:

0xxxxxxx - Lower 7 bit.
10xxxxxx - Second and subsequent bytes in a multi-byte sequence.
110xxxxx - First byte of a two-byte sequence.
1110xxxx - First byte of a three-byte sequence.
11110xxx - First byte of a four-byte sequence.
111110xx - First byte of a five-byte sequence.
1111110x - First byte of a six-byte sequence.

不存在七字节或更大的字节序列。根据UTF-8最新版本,UTF-8序列长度最多只能到4个字节,这将使0xf8-0xff未使用,但可能存在一个字节序列可以根据已过时的版本被有效地称为UTF-8,并包括在0xf8-0xfb之间的八位字节。


现代的UTF-8标准不再允许5字节和6字节序列,因为它们编码的代码点不能在UTF-16中表示。RFC 3629限制最大的字节序列为4,并且Unicode标准采用了这个限制。 - Remy Lebeau
@Remy Labeau,我认为你把UTF-8和CESU-8混淆了。“CESU-8定义了一种与UTF-8相同的Unicode编码方案,除了其对补充字符的表示方式。在CESU-8中,补充字符被表示为六字节序列,由每个UTF-16代理码单元转换成类似于UTF-8转换的八位形式,但不先将输入代理对转换为标量值。”UTF-8没有改变。 - Mike Samuel
@RemyLebeau,您是在指RFC 3629更新“与RFC 2279的更改:将字符范围限制为0000-10FFFF(UTF-16可访问范围)”吗? - Mike Samuel
@RemyLebeau-TeamB,编辑添加了警告。 - Mike Samuel
@Anony-Mousse,没错。 如果您要存储的内容包括不是有效C字符串的值,例如“foo\0bar\0”,那么假设您正在存储C字符串,您将无法得到强大的设计。 - Mike Samuel
显示剩余8条评论

0

1
为什么不使用\0?这是最兼容的。 - Has QUIT--Anony-Mousse
1
\0 是字符串终止符。我相信它会引起问题。 - Ahmed Al Hafoudh
2
为什么,这正是他想做的事情:“终结者在结尾处” - Has QUIT--Anony-Mousse
\0 也是一种合法的 ASCII 编码,因此也是一个代码点的合法 UTF-8 编码。我需要的是明确 不合法 的内容。 - phs
为什么不使用适合此处使用的合法字符? - Has QUIT--Anony-Mousse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接