字符编码:ASCII / GBK / Unicode / UTF-8

一、核心结论

Unicode 是”字典”(给字符发编号)。
ASCII / GBK / UTF-8 是”翻译方式”(把编号变成字节)。


二、字符怎么进电脑?

1
字符"中" → 找到编号(Unicode) → 按某套规则写成字节(具体编码)

两步走:先查编号,再写成字节。


三、Unicode:全球字典

给每个字符发唯一编号:

字符 编号
A U+0041
中 U+4E2D
😀 U+1F600

注意:编号还没变成电脑能存的字节。

类比:Unicode 像一本全球统一的字典,每个字都有页码。但页码本身还没变成硬盘上的 0 和 1。


四、三种编码格式

1. ASCII —— 只够英文

  • 0~127,1 字节
  • A → 65 → 01000001
  • 中文没有 ASCII 编号,存不了

2. GBK —— 中国自己搞的

  • 中文 2 字节,英文 1 字节
  • 只在中国用,不兼容别国

3. UTF-8 —— 全球统一

  • 英文 1 字节、中文 3 字节、emoji 4 字节
  • 变长,省空间,全球通用

五、你卡住的那段,翻译成人话

原文:

1
2
3
4
5
英文字符 → unicode 编号 → ASCII 存
中文字符 → unicode 编号 → GBK 存
【4】诞生 utf-8
英文字符 → unicode 编号 → utf-8 存
中文字符 → unicode 编号 → utf-8 存

翻译:

以前各国各搞一套(英文 ASCII、中文 GBK),混排麻烦、易乱码。
UTF-8 出现,全球统一:所有字符都查 Unicode 编号,再用 UTF-8 存。
这就是”各搞各的”变成”全球统一”。


六、为什么乱码?

存的时候用编码 A,读的时候用编码 B。

类比:用中文写信,对方按英文语法读。

统一 UTF-8 基本不会乱码。


七、易混点

你以为 实际
Unicode 就是 UTF-8 ❌ 一个是字典,一个是存字节方式
ASCII 能存中文 ❌ 只能英文和符号
GBK 是国际标准 ❌ 只是中国标准
UTF-8 每字符 3 字节 ❌ 变长:英1、中3、emoji4

八、Python 实操

1
2
3
4
5
6
7
8
9
# 字符串(Unicode)→ 字节(编码)
"中".encode("utf-8") # b'\xe4\xb8\xad' (3个字节)
"A".encode("utf-8") # b'A' (1个字节)

# 字节 → 字符串(解码)
b'\xe4\xb8\xad'.decode("utf-8") # "中"

# 编码解码不对应,就会乱码
"中".encode("utf-8").decode("gbk") # 乱码!

记忆:encode = 编码(字符→字节),decode = 解码(字节→字符)。


九、实战场景

  • 爬虫乱码:resp.encoding = 'utf-8'
  • 文件读写:open(f, encoding='utf-8')
  • 接口对接:统一 UTF-8 避免乱码
  • 数据库:建库建表指定 utf8mb4,能存 emoji
  • 日志分析:日志编码不对,中文全是问号

十、完整图示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     字符                 Unicode 编号            最终存的字节
(全球唯一字典)
┌────────┐
│ "A" │ ──查字典──→ U+0041 ──UTF-8──→ 01000001 (1字节)
└────────┘
┌────────┐
│ "中" │ ──查字典──→ U+4E2D ──UTF-8──→ 11100100... (3字节)
└────────┘

以前:
"A" ──Unicode──→ U+0041 ──ASCII──→ 1字节
"中" ──Unicode──→ U+4E2D ──GBK────→ 2字节
↑ 两套标准,混着用容易乱

现在:
全部 ──Unicode──→ 编号 ──UTF-8──→ 字节
↑ 一套标准,全球统一