编码-1

文章启发来源:

  1. cnblogshtml

  2. 阮一峰python

  3. 知乎shell

字符编码方式

note from wiki:ubuntu

从维基百科上获得的一些理解,一个字符的unicode编码是肯定的,可是在传输过程当中,因为不一样系统平台的设计不一致,因此对unicode编码的实现方式是有所不一样的。unicode的实现方式成为unicode转换格式(简称UTF)例如对于一个包含基本7位ASCII字符的unicode文件,若是都使用2字节的原unicode编码传输,会形成浪费。对于这种状况可使用UTF-8编码,它是一种变长编码,对于基本ASCII字符仍然采用7位编码表示,占用一个字节。
意思其实就是,unicode规定了符号的二进制代码的符号集,可是并无规定二进制代码应该如何存储。也就是说,在计算机的存储中,一个字符的存放方式并不必定会与它的unicode编码一致。这是由于采用了不一样的编码方式所致使的。segmentfault

本身整理的一些背景:

编码一开始是使用ASCII码来进行编码的,可是这个编码方式是针对英文为基础的国家的。后来,各个地区由于各自的须要,开始使用127位之后的扩展位。好比中国,由于几万个汉字,因此单靠单个127位是根本不够的,因此就规定,使用高于127位的两个字节来表示汉字。固然也就顺便把原来的一些其余扩展西方字符给出从新编码了。即,全角字符(半角字符可类推)GB2312。
后来标准随着发展,GBK变成了GB18030,即,只要第一个字节表示的十六进制数大于127,就表示汉字的开始。(DBCS,双字节字符。台湾地区的BIG5)。
后来unicode开始制定了,它的制定标准在上面的引用中能够看到,使用的是两个字节来表示字符。所以在unicode标准里,不管是汉字的全角字符仍是英语的半角字符,都是一个字符,两个字节。可是unicode如何在网络上传播也是一个问题。因而,便有了UTF。UTF与unicode的转换关系以下:windows

note:网络

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

其中的x是要用左边的十六进制码转化为二进制码后,代替相关的位。UTF-8的编码规则很简单,只有二条:编辑器

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。所以对于英语字母,UTF-8编码和ASCII码是相同的。
    2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一概设为10。剩下的没有说起的二进制位,所有为这个符号的unicode码。

在查阅了几篇blog后,举个例子:好比说你如今的file用的是编辑器等(好比说是windows上的记事本,且设置它为ASCIIunicode(实际上是带BOM的utf-8))默认的编码方式,那么存储的时候用的就是这种编码方式对应的在硬盘中的存储方式。好比说,此刻我用sublime 3打开,并且个人sublime 3 中只有utf系列和一些西文字体的编码方式,那么若是打开的文件用的是ASCII保存的文件,则此时会显示的乱码;而若是使用的是unicode的编码方式,也是能打开的,并且不会出现乱码的状况。
在终端或者编辑器中,若是没有进行特殊声明的话,就会使用它们默认的编码格式进行编码,或者是GBK或者是UTF,若是是ascii的话,汉字字符是没法存储的,由于没有配套的编码。因此通常能显示汉字的地方,使用的是GBK等等编码格式,要转码的话,先转换为unicode,而后再转换为其余东西。模块化

关于python的encoding

参考知乎上的一个回答传送门post

以我本身的理解就是:

  • 首先得分清楚编码问题,在不一样的环境中,编码是不一样的。在终端的状况下,(windows 中是cmd,ubuntu 下的terminal,远程登陆是xshell),因此他们的编码是不一样的。shell环境下,windows的编码是GBK,ubuntu通常是utf-8。-------在文本编辑的状况下,与上面的状况相似,是根据编辑器的状况决定的.

  • 在python中的状况是,unicode(A,B)的意思是用B的编码方案将A解码,并将结果返回为unicode字符串。因此通常在出现UnicodeDecodeError时候,错误的来源应该就是:

  1. 文件保存时的编码方式是编辑器默认的保存方式,而在运行环境中默认的编码方式与该文件方式并不相同,颇有多是有非ANIS的字符出现所致。由于环境没法编码该文件。

  2. 在文件保存的时候,带有BOM 。BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是由于这样能够把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 以外的操做系统里会带来问题。
    因此啊,最后在文件的头里面须要加入utf-8的说明,最好不要用BOM。

一点有意思的扩展,在pythonIDE中

两种终端下的显示

# 环境是sublime 3
    1 >>> u"知乎".encode('utf-8')
    2 '\xe7\x9f\xa5\xe4\xb9\x8e'
    3 >>> u"知乎".encode('gb2312')
    4 '\xd6\xaa\xba\xf5'
    5 >>> '知乎'.encode('utf-8')
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)
   7 >>> '知乎'
     '\xe7\x9f\xa5\xe4\xb9\x8e'
   8 >>> u'知乎'
     u'\u77e5\u4e4e'
   9 >>> u'知乎'.encode('utf-8').decode('utf-8')
     u'\u77e5\u4e4e'    
   
# 环境是windows:
    >>>'知乎'
    '\xd6\xaa\xba\xf5'
    >>>u'知乎'
    u'\u77e5\u4e4e'
    >>> u"知乎".encode('utf-8')
    '\xe7\x9f\xa5\xe4\xb9\x8e'
    >>> u"知乎".encode('gb2312')
    '\xd6\xaa\xba\xf5'
    
    #仍是补充一下举这个例子的本意:
    #从第七行(数字标出的,如下也是同样)以及第一二行中能够看出,两个输出结果是相同的,第一行说明  将    u'知乎'  unicode字符串按照utf-8的编码方式进行编码,并以字节串的形式输出来。
    #可是若是换成的是 u'知乎' 的话,则表示的是将这个汉字用unicode编码的形式存放。(猜想是自动调用了encode方法)。因此呢,第九行意思是将utf-8编码的字符串用utf-8解码出来。
    #下面又在windows上补充了下,能够看出在不一样的终端下,使用的编码方式多是不一样的,好比在windows上就有多是,当输入汉字的时候,终端用gbk的编码方式将汉字编码。

最后再贴一个连接参考blog

总结

在这两天的调试过程当中,开始将unicode的相关知识模块化,因此在此也特意写下这些东西,做为一个总结。在写代码的时候,若是一个文件中有超过ascii的字符的话,那么须要在py文件的第一行加以声明。这是由于不一样的环境,不一样的编译器所默认的编码字符的格式是不一样的。最好可以统一以unicode字符串为基础进行转换。

update

这是一个在segmentfault网站上回答过的一个东西的连接。连接1

相关文章
相关标签/搜索