使用位移位(bit shifting)猜测UTF-8编码的C语言实现问题咨询
使用位移操作实现UTF-8编码识别的核心思路
先明确UTF-8编码的标准字节规则
UTF-8是变长编码,所有字节都符合以下四类格式之一:
- 单字节字符(对应ASCII):最高位为0,格式为
0xxxxxxx - 多字节序列首字节:开头连续N个1后跟1个0,N代表整个序列的总字节数:
- 2字节序列首字节:
110xxxxx - 3字节序列首字节:
1110xxxx - 4字节序列首字节:
11110xxx
- 2字节序列首字节:
- 多字节序列跟随字节:开头固定为
10,格式为10xxxxxx
位移操作的对应实现逻辑
C语言处理时要注意:先把读取到的char值强转为unsigned char类型再做位移,避免有符号char的符号位扩展导致运算结果异常。
1. 单字节字符判断
将字节右移7位,仅保留最高位的1个bit,如果结果为0说明符合单字节规则:
if ((b >> 7) == 0) { /* 合法单字节 */ }
2. 多字节首字节判断
根据右移后保留的高位bit值判断序列长度:
- 2字节首字节:右移5位后保留高3位,值为
0b110(十进制6)else if ((b >> 5) == 0x6) { /* 2字节首字节,后续需要1个跟随字节 */ } - 3字节首字节:右移4位后保留高4位,值为
0b1110(十进制14)else if ((b >> 4) == 0xE) { /* 3字节首字节,后续需要2个跟随字节 */ } - 4字节首字节:右移3位后保留高5位,值为
0b11110(十进制30)else if ((b >> 3) == 0x1E) { /* 4字节首字节,后续需要3个跟随字节 */ }
3. 跟随字节判断
将字节右移6位,保留高2位,如果值为0b10(十进制2)说明符合跟随字节规则:
if ((b >> 6) == 0x2) { /* 合法跟随字节 */ }
整体识别流程
- 初始化一个
remaining_follow计数器,初始值为0,用来记录当前多字节序列还需要匹配的跟随字节数 - 逐字节读取文件内容,对每个字节做以下判断:
- 如果
remaining_follow == 0:判断当前字节属于单字节还是某类多字节首字节,对应设置remaining_follow的值;如果都不符合,直接判定文件不是合法UTF-8编码 - 如果
remaining_follow > 0:判断当前字节是不是合法跟随字节,是则remaining_follow -=1,否则直接判定为非UTF-8
- 如果
- 所有字节遍历完成后,若
remaining_follow != 0,说明存在截断的多字节序列,同样判定为非UTF-8
内容的提问来源于stack exchange,提问作者ninjarubberband
相关产品推荐
相关产品推荐

