检查字节序列是否包含utf-16

时间:2013-01-07 12:54:21

标签: string unicode utf-8 utf-16

我正在从流中读取字节序列。假设为了参数,序列是固定长度的,我将整个事物读入一个字节数组(在我的例子中它是vector<char>,但对于这个问题并不重要)。这个字节序列包含一个字符串,我可以使用utf-16或utf-8编码。不幸的是,没有指出它是哪一个。

我可以验证字节序列是否表示有效的utf-16编码,以及它是否表示有效的utf-8编码,但我也可以成像相同的字节序列可能是有效的utf-8和有效的utf-16同时。

那么,这是否意味着没有办法一般地弄清楚它是哪一个?

2 个答案:

答案 0 :(得分:3)

如果希望使用拉丁文脚本用语言编写内容,只需计算空值就会检测到UTF-16。在UTF-8中,空字节将解码为NUL控制字符,并且它们不会正常显示在文本中。

用其他脚本编写的语言在UTF-16和UTF-8中都不能完全有效,除非它是人工构造的。

因此,首先检测它是否是完全有效的UTF-8序列:

  • 如果是,检查空字节,如果有,则为UTF-16。否则它是UTF-8。
  • 如果没有,那就是UTF-16。

如果上面的结果是UTF-16,那还不够,因为你必须知道结束。使用拉丁文脚本编写的语言,奇数或偶数空字节的数量将告诉您。

答案 1 :(得分:2)

  

那么,这是否意味着没有办法一般地弄清楚它是哪一个?

没错。字节串[0x30, 0x30]可以是UTF-8字符串00或字符的UTF-16编码。如果你想知道的话,那就是WAVY DASH。

还有一些启发式尝试:

  • 您可以检查字符串是否以BOM开头(Windows程序喜欢这些),因为两个BOM都不是UTF-8序列的有效开头。
  • 如果您确定字符串中没有NUL字符,则包含零字节的每个偶数长度字符串必须为UTF-16。

如果失败,你必须默认使用其中一个选项,或者在使用-8和-16解码时对字符串的内容进行某种检查。