1. 编码介绍
- 在计算机中,所有的数据在实际存储的时候都是用二进制来表示的(二进制1、0),那么问题来了,用哪些二进制数字表示哪些字符呢?如果每个人都约定一套自己的对应规则(编码),那么在相互通信的时候(解码),的时候就会很麻烦,因为每种编码方式,都会对应一种解码方式。
2. ASCII码
- 美国国家标准局(ANSI)制定了ASCII码(American Standard Code for Information Interchange,美国标准信息交换码).
- 1位二进制有两种状态:1、0
- 2位二进制数可以有4中组合,可以表示4个字符,那么 7位 二进制数字有 128种组合,可以表示128个字符,称之为:标准的ASCII码。如果用8位表示,可以表示256个字符,减去之前的128个,后面128个称之为 扩展ASCII码。
2. Unicode编码
- 对于英文来说,ASCII码足够用了,但是对于汉语,或者其他字符比较多的语言来说,ASCII码显然不满足要求,因此,出现了unicode编码。
- Unicode 是一个 编码集合,几乎包括了世界上所有的字符,它只规定了符号的二进制代码, 却没有规定这个二进制代码应该如何存储。
- Unicode编码和UCS编码是相同的,如果用2个字节表示字符,这种称之为UCS-2或者UTF-16,如果用4个字节表示字符,这种我们称之为UCS-4,或者UTF-32。
- Unicode编码集的问题:比如, 汉字"严"的unicode是十六进制数4E25, 转换成二进制数足足有15位
(100111000100101), 也就是说这个符号的表示至少需要2个字节. 表示其他更大的符号,可能需要3个字节或者4个字节, 甚至更多.这里就有两个严重的问题, 第一个问题是, 如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号, 而不是分别表示三个符号呢?第二个问题是, 我们已经知道,英文字母只用一个字节表示就够了, 如果unicode统一规定, 每个符号用三个或四个字节表示, 那么每个英文字母前都必然有二到三个字节是0, 这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍, 这是无法接受的. 由此 出现了多种 Unicode 实现方式。
3. UF-8编码
为了方便 Unicode编码的 统一,出现了 utf-8编码。
UTF-8最大的一个特点, 就是它是一种变长的编码方式. 它可以使用1~6个字节表示一个符号, 根据不同的符号而变化字节长度.
-
那么问题来了,unicode编码是如何变成utf-8编码的?首先UTF-8具有下面的特征:
关于上面的特征,我们看看即可,主要是 了解下 转换的规则,这样才能 对 编码有深入的认识。
上图中 左侧表示 unicode编码范围,右侧为 转换后的 utf-8编码的 二进制。
第一个字节要么最高位是0(ASCII字节),要么最高两位都是1,最高位之后1的个数决定后面有多少个字节也属于当前字符编码,例如111110xx,最高位之后还有四个1,表示后面有四个字节也属于当前字符的编码。后面每个字节的最高两位都是10,可以和第一个字节区分开。这样的设计有利于误码同步,例如在网络传输过程中丢失了几个字节,很容易判断当前字符是不完整的,也很容易找到下一个字符从哪里开始,结果顶多丢掉一两个字符,而不会导致后面的编码解释全部混乱了。上面的格式中标为x的位就是UCS编码,最后一种6字节的格式中x位有31个,可以表示31位的UCS编码,UTF-8就像一列火车,第一个字节是车头,后面每个字节是车厢,其中承载的货物是UCS编码。UTF-8规定承载的UCS编码以大端表示,也就是说第一个字节中的x是UCS编码的高位,后面字节中的x是UCS编码的低位。
例如:
-
最后 python里的 编码问题
4. GBK编码
- unicode 编码集的 另外一种实现方式,就是 GBK编码。
- utf-8 和 GBK编码 互转,都 先要转换成 unicode编码 然后才能 互转。