如何以与endian无关的方式读取UTF-16代码点的长度

时间:2016-01-29 23:00:57

标签: c++ unicode endianness utf-16

如果我不提前知道其字节顺序,我如何沿其代码点单步执行UTF-16字符串?在我的代码中,我们假设endianess已经转换为当前架构使用的任何内容,我只想从一个代码点走到下一个代码点。

2 个答案:

答案 0 :(得分:3)

你做不到。考虑字节序列0xD8 0x3D 0xDE 0x00

  • 如果它被读作UTF-16BE,则它是一个代码点:U+1F600()
  • 如果它被读作UTF-16LE,则它是两个代码点:U+3DD8 U+00DE(㷘Þ)

两种解释都是完全有效的,没有一些字节顺序指示器就无法区分它们。

答案 1 :(得分:1)

如果您知道数据的字节顺序,则只能可靠地计算。

这可以通过确保数据以unicode BOM开头来实现:它为大端的0xFE 0xFF和小端的0xFF 0xFE。因此,对于您阅读的16位字符wc,(wc>>8==0xFE)会告诉您字节序。

没有BOM,你永远无法确定它是BE还是LE,除非你在surrogate pairs中发现一些编码不一致,这表明你的字节序假设是错误的(即16位字符是0xD800-0xDFFF范围和另一个范围与形成代理对的条件不匹配)。

您还可以尝试通过使用一些基本统计信息,使用换行符(如果它是多行文本)或在文本中使用空分布(参见例如this library)来进行有根据的猜测。但无论你发现什么,你都无法确定你是否已经确定了正确的结尾。