python编码问题

Posted by yan on September 6, 2019

常用编码

  1. ASCII编码:
    8个比特作为一个字节(byte)
  2. Unicode编码:
    常用的是2个字节表示一个字符,所以用Unicode编码比ASCII编码要多一倍的存储空间。
  3. UTF-8编码(可变长编码):
    UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编译成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字符。
  4. GB2312简体中文编码:
    一个汉字占用2个字节,该编码遇到繁体中文、日文、韩文时,这些文字内容无法被正确编码。
  5. BIG5繁体中文编码:
    在台湾地区使用。
  6. GBK编码:
    支持简体及繁体中文,但对他国非拉丁字母还有问题。可以表示21886个字符。
  7. GB18030字符集:
    解决了中文、日文、朝鲜语系的编码,兼容GBK,可以表示27484个文字。
    1
    2
    3
    4
    
    ep:
    字符      ASCII           Unicode                    UTF-8
     A      01000001     00000000 01000001             01000001
     中        X         01001110 00101101     11100100 10111000 10101101
    

    编码原理

      在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或需要传输的时候,就转换为UTF-8编码。
    以记事本为例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
                               Unicode编码
                     ↗                           |
                     |                           ↘
                 读取,转换为Unicode         保存,转换为UTF-8编码
                     ↗                           |
                     |                           |
                   txt文件                     txt文件
                     ↗                           |
                     |                           ↘
                                 UTF-8编码
    

    编码介绍

    1.ANSI–> ASCII 用于保存英文文字
      一个字节,共有8个比特位,有256个字符,其中ASCII使用了127个,用于表示所有的空格、标点符号、数字、大小写字母。
      采用127号之后的空位来表示这些新的字母、符号,加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了 最后一个状态255。从128到255这一页的字符集被称”扩展字符集。
    2.GB2312(扩展了ANSI)
      用两个字节表示,一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符,而原来在127号以下的那些就叫”半角”字符了
    3.GBK(扩展了GB2312)
      GBK不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。后来少数民族也要用电脑了,我们再扩展,又加了几千个新的少数民族的字,GBK 扩成了 GB18030。
    4.Unicode(统一规范)
      一律使用2个字节,即16位统一表示所有的字符。
    Unicode与UTF-8编码转换规则

    1
    2
    3
    4
    
    Unicode               -->            UTF-8
    0000 – 007F                            0xxxxxxx                    1个字节
    0080 – 07FF                       110xxxxx 10xxxxxx                2个字节
    0800 – FFFF                    1110xxxx 10xxxxxx 10xxxxxx          3个字节
    

    举例说明该转换规则:
      汉字‘汉’的Unicode编码对应是6C49,在6C49位于0800-FFFF之间,所以要用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 1100 0100 1001,将这个比特流按三字节模板的分段方法分为0110 110001 001001,依次代替模板中的x,得到:1110-0110 10-110001 10-001001,即E6 B1 89,这就是其UTF8的编码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
                                6C49
                           0800<6C49<FFFF
                 模版:1110xxxx 10xxxxxx 10xxxxxx
                                6C49         Unicode编码
                                 |
                   0110    1100   0100    1001
                                 |
                     0110    110001     001001
                                 |  带入模版,替换X
                 11100110    10110001    10001001
                                 |
               1110    0110   1011   0001   1000   1001
                                 |
                         E6     B1     89      UTF-8编码
    

    python编码

      字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即现将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另外一种编码。原有编码–>内部编码Unicode–>目标编码
      decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode(‘gb2312’),表示将gb2312编码的字符串转换成unicode编码。
      encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode(‘gb2312’),表示将unicode编码的字符串转换成gb2312编码。
    over