Python 运维程序员

字符编码问题:Unicode 和 UTF-8

2017-11-18  本文已影响142人  大富帅

Unicode

Unicode 是一种编码,它将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码。这样乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。
Unicode 是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样。

Unicode问题

Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字“ 金 ”的 Unicode 是十六进制数91D5,转换成二进制数足足有15位( 1001 0001 1101 0001),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题:

UTF-8

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一
UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
----------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

还是以字来讲解, 的unicode码是91D1(16进制), 对应的二进制是: 1001 0001 1101 0001(二进制),它在unicode的第三个范围,0000 0800-0000 FFFF , 所以如果它要用utf-8来表示的话, 就要按找utf-8定义的规则 1110xxxx 10xxxxxx 10xxxxxx来转成utf-8的编码。
最后转换的UTF-8结果就是:11101001 10000111 10010001
而这个UTF-8的码是二进制的,转成16进制就是 e9 87 91 (十六进制)
然后转成我们平常python 打印字符时候显示的UTF-8字符 \xe9\x87\91
\x是个分隔符。

UTF-8 GBK UTF8 GB2312 之间的区别和关系

UTF-8:Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。

GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。

GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:
GBK、GB2312--Unicode--UTF8
UTF8--Unicode--GBK、GB2312

因为unicode 定义所有字符都有唯一的二进制, 所以任何的编码转换都要转成unicode作为中介,然后再根据各个编码规则,自己转成自己的编码

总结

unicode 转成utf-8 步骤 :
1.查询到的unicode 是 91d1
2.91d1 在unicode符号范围 0000 0800-0000 FFFF 里面, 对应的utf-8规则是 1110xxxx 10xxxxxx 10xxxxxx
3.91d1转成二进制是: 10010001 11010001
4.然后将91d1 的二进制 10010001 11010001按规则转成utf-8的 11101001 1000 0111 1001 0001
5.utf-8的二进制 11101001 1000 0111 1001 0001 转成 utf-8的十六进制是 e1 87 91
6.所以最后 utf-8字符就是 \xe1\x87\x91

参考

字符编码笔记:ASCII,Unicode 和 UTF-8

上一篇 下一篇

猜你喜欢

热点阅读