使用位移位猜测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 理论上支持延伸到六个字符的字节序列,但实际上只使用四个):
0*
(您必须小心地将其与常规 ASCII 文件区分开来)
110*
, 10*
1110*
, 10*
, 10*
11110*
, 10*
, 10*
, 10*
检查这些很容易:
要检查 unsigned char a
是否符合其中一种模式,运行:
- 对于
10*
- 最常见的模式 - 使用 (a >> 6) == 0x2
.
- 对于
0*
- 使用 (a >> 7) == 0x0
.
- 对于
110*
- 使用 (a >> 5) == 0x6
.
- 对于
1110*
- 使用 (a >> 4) == 0xe
.
- 对于
11110*
- 使用 (a >> 3) == 0x1e
.
我们所做的只是将位右移并检查它们是否等于 UTF-8 字节序列中的位。
我正在编写一个类似 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 理论上支持延伸到六个字符的字节序列,但实际上只使用四个):
0*
(您必须小心地将其与常规 ASCII 文件区分开来)110*
,10*
1110*
,10*
,10*
11110*
,10*
,10*
,10*
检查这些很容易:
要检查 unsigned char a
是否符合其中一种模式,运行:
- 对于
10*
- 最常见的模式 - 使用(a >> 6) == 0x2
. - 对于
0*
- 使用(a >> 7) == 0x0
. - 对于
110*
- 使用(a >> 5) == 0x6
. - 对于
1110*
- 使用(a >> 4) == 0xe
. - 对于
11110*
- 使用(a >> 3) == 0x1e
.
我们所做的只是将位右移并检查它们是否等于 UTF-8 字节序列中的位。