字符编码:ASCII 和 Unicode
ASCII和Unicode都是计算机用来表示字符的编码标准。简单来说,ASCII 是 Unicode 的子集,Unicode 是现代编程的通用标准。
一、ASCII:早期的字符集
ASCII(美国信息交换标准代码)诞生于 1960 年代,是计算机最基础的字符编码标准。它用7 位二进制表示一个字符,总共可以表示 128 个字符(0-127)。
┌─────────────────────────────────────────────────────────────┐ │ ASCII 字符集 (0-127) │ ├───────────────┬─────────────────────────────────────────────┤ │ 0-31 │ 控制字符(不可打印) │ │ 32 │ 空格 │ │ 33-47 │ ! " # $ % & ' ( ) * + , - . / │ │ 48-57 │ 0-9(数字) │ │ 58-64 │ : ; < = > ? @ │ │ 65-90 │ A-Z(大写字母) │ │ 91-96 │ [ \ ] ^ _ ` │ │ 97-122 │ a-z(小写字母) │ │ 123-127 │ { | } ~ DEL(删除) │ └───────────────┴─────────────────────────────────────────────┘特点:
只支持英文字母、数字、标点符号
无法表示中文、日文、韩文等非英语字符
Python 示例:
# 字符 ↔ ASCII 码转换 print(ord('A')) # 65 print(chr(65)) # 'A' print(ord('0')) # 48 print(chr(97)) # 'a'二、ASCII 的局限:多语言无法兼容
ASCII 只用了 7 位,而计算机存储的基本单位是字节(8 位),多出来的 1 位是空闲的。于是各国开始用这多出来的一位来定义自己的编码:
| 编码 | 语言 | 说明 |
|---|---|---|
| GB2312/GBK | 中文 | 中国国家标准 |
| Shift-JIS | 日文 | 日本标准 |
| EUC-KR | 韩文 | 韩国标准 |
问题:
同一个 0x80-0xFF 字节,在不同国家编码中代表不同字符 →乱码
不同语言编码互不兼容 →无法混合使用
三、Unicode:统一所有字符的万国码
Unicode的目标是统一世界上所有文字,为每一个字符分配一个唯一的编号(码点,Code Point)。
相关概念:
1. 码点(Code Point)
每一个字符对应的唯一数字编号。
┌─────────────────────────────────────────────────────────────┐ │ Unicode 码点示例 │ ├─────────────────────────────────────────────────────────────┤ │ 'A' → U+0041 │ │ '中' → U+4E2D │ │ '😊' → U+1F60A │ │ 'DŽ' → U+01C4 │ └─────────────────────────────────────────────────────────────┘2. 平面(Plane)
Unicode 目前有 17 个平面,每个平面包含 65536 个码点。
| 平面 | 范围 | 内容 |
|---|---|---|
| BMP(基本多文种平面) | U+0000 ~ U+FFFF | 最常用字符(含中文、英文、常用符号) |
| 辅助平面 | U+10000 ~ U+10FFFF | 生僻字、Emoji(如 😊) |
3. 编码方式:UTF-8、UTF-16、UTF-32
Unicode 只是给字符分配了编号,还需要规定这个编号在计算机中如何存储,这就是UTF-8、UTF-16、UTF-32。
| 编码 | 可变长 | 特点 | 适用场景 |
|---|---|---|---|
| UTF-8 | 是(1-4 字节) | 兼容 ASCII,节省空间 | 互联网标准,最常用 |
| UTF-16 | 是(2 或 4 字节) | 对中文等较紧凑 | Windows、Java 内部 |
| UTF-32 | 否(4 字节) | 固定长度,处理快 | 内存大、处理方便的场景 |
UTF-8 的编码规则:
┌─────────────────────────────────────────────────────────────┐ │ UTF-8 编码规则 │ ├───────────────┬─────────────────────────────────────────────┤ │ 码点范围 │ UTF-8 字节序列 │ ├───────────────┼─────────────────────────────────────────────┤ │ U+0000 ~ U+007F│ 0xxxxxxx(1字节,兼容 ASCII) │ │ U+0080 ~ U+07FF│ 110xxxxx 10xxxxxx(2字节) │ │ U+0800 ~ U+FFFF│ 1110xxxx 10xxxxxx 10xxxxxx(3字节) │ │ U+10000~U+10FFFF│ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(4字节)│ └───────────────┴─────────────────────────────────────────────┘Python 示例:
# 字符 → Unicode 码点 print(hex(ord('A'))) # 0x41 print(hex(ord('中'))) # 0x4e2d # 码点 → 字符 print(chr(0x4E2D)) # '中' print(chr(0x1F60A)) # '😊' # UTF-8 编码 print('中'.encode('utf-8')) # b'\xe4\xb8\xad' print('中'.encode('utf-8').hex()) # e4b8ad四、ASCII 和 Unicode 的关系
ASCII 是 Unicode 的真子集:ASCII 的 0-127 个字符,在 Unicode 中的码点相同,也是 U+0000 ~ U+007F
UTF-8 编码中,ASCII 字符占 1 字节,完全兼容 ASCII,所以很多文本文件看不出区别。
五、其他
| 场景 | 建议 |
|---|---|
| 内部处理 | 使用 Unicode 字符串(Python 3 默认) |
| 网络传输/文件存储 | 使用UTF-8编码 |
| 打开文件 | 指定encoding='utf-8' |
| HTTP 响应 | 设置Content-Type: text/html; charset=utf-8 |
| 数据库连接 | 字符集设置为utf8mb4(MySQL)或UTF-8(PostgreSQL) |
Python 示例:
# 写入 UTF-8 文件 with open('file.txt', 'w', encoding='utf-8') as f: f.write('Hello 世界 😊') # 读取 UTF-8 文件 with open('file.txt', 'r', encoding='utf-8') as f: content = f.read() print(content)| 概念 | 说明 |
|---|---|
| ASCII | 7 位编码,128 个字符,仅支持英文 |
| Unicode | 统一字符集,为每个字符分配唯一码点 |
| UTF-8 | Unicode 的存储方式,变长编码,兼容 ASCII |
| Python 3 | 字符串默认使用 Unicode |
其实ASCII 是过去时,而Unicode 是现在时,UTF-8 是通用存储格式。 在 Python 3 中,字符串默认就是 Unicode,读写文件时记得指定encoding='utf-8'。
