中文乱码分析

由于世界各地文字多样,计算机世界产生了很多编码。 编码就是以一种规则解释二进制机器码,不同文字的机器码是一样的,都是 0101 序列。 因此以一种方式编码,再以另一种方式解码就可能产生乱码。

不知道乱码的英文是什么?

中文乱码

以中文编码为例,中文编码主要包括

  • GBK
  • GB2312(大陆制定的简体字编码)
  • BIG5(台湾制定的繁体汉字编码)
  • UTF-8
  • ISO8859-1

ISO8859-1 无法编码汉字?

常见乱码

(Python 程序生成,错误处理方式默认 strict,出现错误采用 replace)

码名示例特征原因
原码你好,很高兴认识你。现在我来向你展示计算机编解码错误导致的乱码。
方块码��ã��ܸ�����ʶ�㡣������������չʾ��������������µ����롣黑底问号方块GBK 编码,UTF-8 解码
古文码浣犲ソ锛屽緢楂樺叴璁よ瘑浣犮�傜幇鍦ㄦ垜鏉ュ悜浣犲睍绀鸿�$畻鏈虹紪瑙g爜閿欒��瀵艰嚧鐨勪贡鐮併��古文夹杂日韩文UTF-8 编码,GBK 解码
拼音码ÄãºÃ£¬ºÜ¸ßÐËÈÏʶÄã¡£ÏÖÔÚÎÒÀ´ÏòÄãչʾ¼ÆËã»ú±à½âÂë´íÎóµ¼ÖµÄÂÒÂë¡£带帽的字母GBK 编码,ISO8859-1 解码
符号码你好,很高兴认识你。现在我来向你展示计算机编解码错误导致的乱码。奇怪的符号UTF-8 编码,ISO8859-1 解码
问号码你好,很高兴认识你�?�现在我来向你展示�?�算机编解码错�??导致的乱码�??大部分正常,结尾有问号UTF-8 编码,GBK 解码后再编码,UTF-8 解码
锟斤拷码锟斤拷茫锟斤拷芨锟斤拷锟斤拷锟绞讹拷恪o拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟秸故撅拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟铰碉拷锟斤拷锟诫。锟斤拷GBK 编码,UTF-8 解码后再编码,GBK 解码

附 Python 程序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
table = [
    ('码名', '示例', '特征', '原因'),
    (':----:', ':----:', ':----:', ':----:'),
]

# 原码
word = '你好,很高兴认识你。现在我来向你展示计算机编解码错误导致的乱码。'
table.append(('原码', word, '', ''))

# 编解码错误的处理方式包括:strict(by default), ignore, replace, e.t.c.
# 以下默认采用 strict,有错误采用 replace

# GBK 编码,UTF-8 解码
table.append(
    (
        '方块码',
        word.encode('gbk').decode('utf-8', errors='replace'),
        '黑底问号方块',
        'GBK 编码,UTF-8 解码',
    )
)

# UTF-8 编码,GBK 解码
table.append(
    (
        '古文码',
        word.encode('utf-8').decode('gbk', errors='replace'),
        '古文夹杂日韩文',
        'UTF-8 编码,GBK 解码',
    )
)

# GBK 编码,ISO8859-1 解码
table.append(
    (
        '拼音码',
        word.encode('gbk').decode('iso8859-1', errors='replace'),
        '带有注音符号的字母',
        'GBK 编码,ISO8859-1 解码',
    )
)

# UTF-8 编码,ISO8859-1 解码
table.append(
    (
        '符号码',
        word.encode('utf-8').decode('iso8859-1', errors='replace'),
        '奇怪的符号',
        'UTF-8 编码,ISO8859-1 解码',
    )
)

# ISO8859-1 无法编码汉字?
# word.encode('iso8859-1','ignore') == b''

# UTF-8 编码,GBK 解码后再编码,UTF-8 解码
table.append(
    (
        '问号码',
        word.encode('utf-8')
        .decode('gbk', errors='replace')
        .encode('gbk', errors='replace')
        .decode('utf-8', errors='replace'),
        '大部分正常,结尾有问号',
        'UTF-8 编码,GBK 解码后再编码,UTF-8 解码',
    )
)

# GBK 编码,UTF-8 解码后再编码,GBK 解码
table.append(
    (
        '锟斤拷码',
        word.encode('gbk')
        .decode('utf-8', errors='replace')
        .encode('utf-8', errors='replace')
        .decode('gbk', errors='replace'),
        '锟斤拷',
        'GBK 编码,UTF-8 解码后再编码,GBK 解码',
    )
)


# --- 生成 Markdown 表格 --- #
with open('./table.md', 'w', encoding='utf-8') as fp:
    for line in table:
        fp.write('| {} |\n'.format(' | '.join(line)))
Built with Hugo
Theme Stack designed by Jimmy