使用位移位猜测UTF-8编码

Using bit shifting to guess UTF-8 encoding

我正在编写一个类似 file(1) 的程序,它可以猜测文本文件是否包含 ascii 字符、ISO-8859-1 字符或 UTF-8。 我已经将它编程为猜测 ascii 和 ISO,只剩下 UTF-8。我的问题是我应该使用位移位,虽然我知道位移位的基本知识,但我无法弄清楚如何使用它来猜测 UTF-8 字符。 我当然不是在寻求解决方案,但如果有人能把我推向正确的方向,我会很高兴!

我在用C写

对此的任何解决方案都将基于启发式。但一般来说,UTF-8有以下字节序列(在man utf8中可用):

0x00000000 - 0x0000007F:
    0xxxxxxx
0x00000080 - 0x000007FF:
    110xxxxx 10xxxxxx
0x00000800 - 0x0000FFFF:
    1110xxxx 10xxxxxx 10xxxxxx
0x00010000 - 0x001FFFFF:
    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

所以你的启发式可以向前看几个字节,看看字节是否遵循四种模式之一(UTF-8 理论上支持延伸到六个字符的字节序列,但实际上只使用四个):

  1. 0*(您必须小心地将其与常规 ASCII 文件区分开来)
  2. 110*, 10*
  3. 1110*, 10*, 10*
  4. 11110*, 10*, 10*, 10*

检查这些很容易:

要检查 unsigned char a 是否符合其中一种模式,运行:

  1. 对于 10* - 最常见的模式 - 使用 (a >> 6) == 0x2.
  2. 对于 0* - 使用 (a >> 7) == 0x0.
  3. 对于 110* - 使用 (a >> 5) == 0x6.
  4. 对于 1110* - 使用 (a >> 4) == 0xe.
  5. 对于 11110* - 使用 (a >> 3) == 0x1e.

我们所做的只是将位右移并检查它们是否等于 UTF-8 字节序列中的位。