运行环境
- python3.7
实现思路:
gb2312在文件中的二进制使用的机内码,这里需要区分一下区位码和机内码(这里忽略了国标码的介绍,感兴趣的可以去百度一下)。
- 区位码是gb2312表上每一个字符对应的位置的编码,gb2312将字符集分成了94个区,一个区内又有94个字符,区内码=区号(2位) 区内位置(2位)。
- 机内码则是gb2312在机器内的表示,机内码=区位码+0xA0A0H。
由此我们也可以知道gb2312的编码范围为0xA1A1-0xFEFE
因此接下的事情就是每两个字符判断一下它们的取值范围,如果满足则说明是gb2312编码
这里再说一下全角字符和半角字符的区别,在gb2312中,全角字符占2个字节,而半角字符只占1个字节,对于第三区位的字符来说,半角字符的值=全角字符的第二个字节-0x80H。
第三区位的区位表
下面是实现的代码,这里注意的是转化的全角仅仅包括第三区位的符号,并没有包括空格,空格全角的机内码为0xA1A1,半角的十六进制码为0x20,如果需要可以自行添加转化。
def f2b(contents: bytes):
r = bytearray()
skip = False
for i in range(len(contents) - 1):
if skip:
skip = False
continue
t1 = contents[i]
t2 = contents[i + 1]
# GB2312的机内码的编码范围
if 0xA1 <= t1 <= 0xFE and 0xA1 <= t2 <= 0xFE:
# 第三区位的字符,即要替换的全角字符所在的区位
if t1 == 0xA3:
r.append(t2 - 0x80)
else:
r.append(t1)
r.append(t2)
# 两个字节都添加,则要跳过下一个字节
skip = True
else:
r.append(t1)
# 补充末尾,如果最后没有跳过字符的话
if not skip:
r.append(contents[-1])
return r