1

搞懂各种编码

作为新手,初上手写代码,在开发过程中逐渐发现对于各种编码的属性和意义都有了更深入的理解,随之也更加不清楚各种编码之间的关系以及如何转换。本文章通过整理总结各种编码,帮助自己了解在各种环境下应该使用何种编码,希望以后不会再迷惑。

编码简介:

1.Unicode家族

Unicode:严格来说,Unicode不是一种编码方式,只能说它是一种编号与字符的映射方法,虽然用这种映射方法目前可以将世界上所有的符号都做到一一对应,但是它并没有指定每个符号需要用多大的空间存储。对于占用4byte的符号,可以使用4字节存储,但是仅占用1字节的符号根本不需要4字节空间,这样会造成极大地浪费,但是如果你的字符长短是变化的,计算机是无法识别的。所以UTF-X就是为了解决这个问题而产生的的解决方案。
笔记:Unicode并不是编码方式,只有变成UTF-X之后才能算是一种编码方式。但是UTF-X都是基于Unicode这套映射关系的。也可以说是Unicode的实现方式。
UTF-8:这是一种可变长度的编码方式,可以使用1-4个字节表示一个符号。目前来说最常用,因为最省空间,机制也最早并最完善。汉字一般用3字节表示,生僻字用4-6字节表示。那么问题来了,计算机如何区分这种长度不同的编码方式呢?了解了编码方式之后,我认为它与哈夫曼树的原理类似。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
这个机制可以很好地让计算机识别出这个Unicode是几个字节。编码规则的示意图如下,从这里也可以看出UTF-8编码方式最长也能达到六个字符:

clipboard.png
UTF-16:同样的道理,UTF-16是以2字节为一个基本单位来表示字符,同样可变长,但是基数是2字节,也就是说它理论上可以扩展为4字节、6字节、8字节……
UTF-32:同样的道理,UTF-32是以4字节为一个基本单位来表示字符,同样可变长,但是基数是4字节。扩展规则同上。

2. ASCII

美国人搞出来的编码
8bit编码 规定了128个字符,第一位为0:0xxxxxxx
数字、大小写字母、英文标点、打印不出来的控制符

3. ISO

欧洲人搞出来的编码,全称为ISO-8859-1(又名Latin1)后升级为ISO-8859-15
8bit编码,兼容ASCII并且充分利用了第一位bit
欧洲国家乱七八糟的语言里面的字符都有了

4. 中文编码家族

1. GB2312:
信息交换用汉字编码字符集,为了表示基数庞大的汉字的一种编码。
2字节(16bit)表示一个汉字,理论上能表示65536个汉字
每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。每区含有94个汉字/符号。这种表示方式也称为区位码。
01-09区为特殊符号。
16-55区为一级汉字,按拼音排序。
56-87区为二级汉字,按部首/笔画排序。
10-15区及88-94区则未有编码。
“高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上 0xA0)。 由于一级汉字从16区起始,汉字区的“高位字节”的范围是0xB0-0xF7,“低位字节”的范围是0xA1-0xFE,占用的码位是 72*94=6768。其中有5个空位是D7FA-D7FE。
例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节) 0xA1(第二个字节)储存。区位码=区字节+位字节(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。这里挺有意思,第一个从1开始而不是从0开始。
2. GBK:
汉字内码扩展规范。是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。

常用场景

python2.X:按照系统来区分编码格式,有单独的Unicode格式
python3.X: 统一为Unicode格式
Windows: GB2312 GBK
Linux: UTF-8 (有的时候,开发同一个项目,Windows终端和Mac终端会遇到编码乱码的问题,应该就是默认编码格式的问题)
所以在使用python2.X的时候会经常遇到编码格式的问题,因为输入的字符串如果不指定为Unicode,那就会使用系统的编码格式解码,这时会产生问题。

感谢:

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
https://www.cnblogs.com/dhsz/p/7737480.html
百度百科相关词条

御龙镜中潜
62 声望4 粉丝

The more I have learnt, the more I need to learn.