浅谈计算机字符编码
程序员如果不弄懂字符编码它就会像幽灵一般纠缠你整个职业生涯,各种灵异事件会接踵而来,挥之不去。
--- 刘志军 [知乎]
基础知识:
1 bit = 1 位 = 2 种两种可能性(0或1)
1 byte = 1 字节 = 1 个英文字符 = 8 bit = 2 ^ 8 次方 = 256 种可能性
一、字符编码简介
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示 1 和 0),而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码规则)。
ASCII
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)
是一种单字节的编码方案,指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符,主要用于显示现代英语。
MBCS
MBCS(Muilti-Bytes Charecter Set,多字节字符集)
使用两个字节来代表一个字符的各种汉字延伸编码方式,又称为 ANSI 编码。
在简体中文系统下,ANSI 编码代表 GB2312 编码;日文操作系统下,ANSI 编码代表 Shift_JIS 编码;韩文操作系统下,ANSI 编码代表 Euc-kr 编码。
不统一的编码标准会不可避免地出现冲突。
GBK 和 gb2312
见上
UCS
Universal Character Set, UCS(中文:通用字符集)是由 ISO 制定的 ISO 10646(或称 ISO/IEC 10646)标准所定义的标准字符集。
UCS-2:使用两个定长的字节来表示一个字符。
UCS-4:是一个更大的尚未填充完全的 31 位字符集,加上恒为 0 的首位,共需占据 32 位,即四字节。理论上最多能表示 231 个字符,完全可以涵盖一切语言所用的符号。
Unicode
Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。
Unicode 伴随着 UCS 的标准而发展,至今仍在不断增修,每个新版本都加入更多新的字符。
当前实际应用的 Unicode 版本对应于 UCS-2,每个字符占用两个字节。
由于计算机的内存比较大,并且字符串在内容中表示时也不会特别大,所以在计算机内存中使用 Unicode 来处理字符。
UTF-8
UTF-8(8-bit Unicode Transformation Format)是一种针对 Unicode 字符集 的可变长度字符编码规则。
UTF-8 使用一至四个字节为每个字符编码,可以用来表示 Unicode 标准中的任何字符。
UTF-8 的特点是对不同范围的字符使用不同长度的编码。对于 0x00-0x7F 之间的字符,UTF-8 编码与 ASCII 编码完全相同,因此可以说 ASCII 是 UTF-8 的子集。
UTF-16 和 UTF-32
Unicode 和 UTF-8 的区别
UTF,是为 Unicode 字符集设计的一种在存储和传输时节省空间的实现方式。
简单来说:Unicode 是「字符集」,UTF-8 是「编码规则」。
从通信角度的理论来说:unicode 是信源编码,对字符集数字化;UTF-8 是信道编码,为更好的存储和传输。
| Unicode 编码(十六进制) | UTF-8 字节流(二进制) |
|---|---|
| 00000000 - 0000007F | 0xxxxxxx |
| 00000080 - 000007FF | 110xxxxx 10xxxxxx |
| 00000800 - 0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
| 00010000 - 001FFFFF | 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx |
| 00200000 - 03FFFFFF | 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
| 04000000 - 7FFFFFFF | 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
二、Python 中字符编码问题
在 Python 中,解释器会在解释执行代码前,先将代码通过系统默认编码方式读入系统内存,再由编译器以特定编码格式编码交付虚拟机解释执行。
即在 Python 2.x 中,解释器默认会将代码以 ASCII 编码方式读入系统内存,但编译器却不会在内存中将代码自动转换为 Unicode;
而在 Python 3.x 中,解释器默认会将代码以 UTF-8 编码方式读入系统内存,并且编译器会在内存中将代码自动转换为 Unicode。
Python 查看系统默认编码格式问题
在 Python2.x 的版本中,系统默认编码格式为 ascii,我们可以通过以下代码查看 Python 的系统默认编码:
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
Python2.x 文件头部设置编码格式
当我们在 Python2.x 文件的开头加上 # -*- coding: gbk -*- 或 # encoding=utf-8 时,会告诉 Python 解释器读取该文件时的编码方式是 utf-8,这时,Python 解释器便会将代码通过 UTF-8 的方式读入系统内存,同时编译器也只会把代码以 UTF-8 的编码格式交付虚拟机解释执行。
Python2.7 编码处理
- 将 unicode 输出成中文:
>>> unic ='\u4f60\u597d' >>> print(unic.decode('unicode-escape')) 你好
Python3.x 编码处理
- 将 unicode 输出成中文:
>>> unic
图解
graph TB
Unicode --> |encode| GBK
Unicode --> |encode| UTF-8
GBK --> |decode| Unicode
UTF-8 --> |decode| Unicode
sequenceDiagram
Unicode码->>字符:decode(unicode-escape)
字符->>Unicode码:encode(unicode-escape)
参考来源
zh.wikipedia.org/wiki/Unicod…
foofish.net/unicode_utf…
www.zhihu.com/question/31…