字符编码详解

Character Encoding Explained

Posted by Marlin on November 11, 2025

字符编码详解

基本概念

  • 字符(character): 人类可读的符号,比如A、中、😊等。
  • 字节(Byte):计算机存储的基本单位,8位二进制数。
  • 编码(Encoding):将字符映射为字节的规则或标准。

字符编码就是:字符 <–> 字节 的映射规则。

字符编码的历史演进

年代 编码名称 特点 问题
1963 ASCII 7位,128个字符,英文够用 不支持其他语言
1980s ISO-8859-1 (Latin-1) 8位,扩展了西欧字符 不支持中文、日文等
1990s GB2312 中国国标,支持简体中文 字符集小,生僻字没有
1995 GBK GB2312 扩展,支持繁体、生僻字 仅中文,跨平台差
2000 GB18030 国标强制标准,兼容Unicode 复杂,部分系统不支持
1991 Unicode 诞生 统一全球字符,字符集无限大 编码方案未定
1993 UTF-16 Unicode 编码方案之一 固定2字节,浪费空间
2008 UTF-8 成为主流 变长编码,节省空间,兼容ASCII 无缺点,现已成为互联网标准

三大主流字符编码

ASCII (美国信息交换标准代码)

  • 范围:0~127 (7位)
  • 内容:英文字母、数字、基本标点符号和控制字符
  • 示例:
1
'A' -> 65(10进制) -> 01000001(二进制)

GBK(中国国家标准扩展编码)

  • 双字节编码:英文字符1字节,中文字符2字节
  • 兼容ASCII:英文字符不变
  • 问题:
    • 不支持日文、韩文等其他语言
    • 跨平台乱码常见(Windows 默认编码)

UTF-8 (8位可变长度编码)

  • 变长编码:
    • 1字节:ASCII字符 (0~127)
    • 2字节:拉丁文扩展等(128~2047)
    • 3字节:中日韩字符(2048~65535)
    • 4字节:少数生僻字、表情符号等(65536及以上)
  • 优点:
    • 兼容 ASCII
    • 节省空间(英文文本小)
    • 全球通用,支持所有语言字符
  • 示例:
1
2
3
'A' -> 41(十六进制)
'中' -> E4 B8 AD
'😊' -> F0 9F 98 8A

UTF-8 与 Unicode 的关系:Unicode 是字符集,UTF-8 是编码方式。

编码与解码的过程

编码 (Encoding)

把字符变成字节

1
2
3
text = "中文"
byte_data = text.encode('utf-8')
print(byte_data)  # b'\xe4\xb8\xad\xe6\x96\x87'

解码 (Decoding)

把字节还原成字符

1
2
3
byte_data = b'\xe4\xb8\xad\xe6\x96\x87'
text = byte_data.decode('utf-8')
print(text)  # 中文

乱码的本质

乱码 = 编码和解码用的规则不一致

示例:

1
2
3
4
5
text = "中文"
byte_data = text.encode('utf-8')

# 错误地用 GBK 解码
print(byte_data.decode('gbk'))  # 输出:涓枃(乱码)

BOM (字节顺序标记)

BOM 是字节顺序标记(Byte Order Mark),用于标识文本文件的编码格式。

是一段放在文件最开头的特殊字节序列,用来告诉别人:“我这份数据到底用的是什么 Unicode 编码方案,以及字节序是大端还是小端。”

总结 (字符编码家谱)

1
2
3
4
5
6
7
8
9
10
ASCII
 │
 ├── ISO-8859-1(Latin-1)
 │
 ├── GB2312 → GBK → GB18030(中文)
 │
 └── Unicode
      ├── UTF-8(互联网标准)
      ├── UTF-16(Windows、Java)
      └── UTF-32(很少用)