编码问题总结

总结下编码问题的相关概念。

字符集和编码的区别

  • 字符集(Character Set)是字符的集合,即为每一个字符分配一个唯一的ID(码点,Code Point)。

  • 编码(Encoding)是把码点转化为字节序列的规则。因为在实际存储中不一定是直接存储字符的码点(比如为了节约空间),所以需要一种转换规则,这种规则就是编码

  • ASCIIGB2312GBK都是字符集,同时它们也代表了对应的编码方式(不严格区分)。

  • Unicode是一种字符集,但它的编码方式有多种,如utf-8utf-16

各种字符集和编码

  • ASCII:储存所有英文字符和部分符号,由0~127表示,每个字符为1字节。

  • GB2312:ASCII码的中文扩展,小于127的字节与原来相同,而用两个大于127的字节来表示中文,加入了大约7000个汉字。同时把ASCII码中的原有字符重新编

  • GBK:是对gb2312的扩展,规定只要高字节大于127则就表示这是一个汉字的开始,从而又增加了20000多个汉字。后来又加入几千个少数民族的字,扩展为GB18030

  • ANSI:不同国家制定了不同标准,包括美国的ASCII,中国的GBK,日本的Shift_JIS,韩国的Euc-kr等。这些不同国家的编码标准合称为ANSI编码。不同的ANSI编码之间互不兼容,对于简体中文系统,ANSI编码就等同于GBK编码。

  • Unicode:是一套字符集,包括了世界上所有的文字和符号。总空间为17个平面(0x0000~0x10ffff),最常用的0号平面(MBP)包含65535个码点,以2个字节表示。

  • UTF-8:unicode的一种编码方式,将一个码位编码成1~4字节。
    对于单字节的字符,字节的第一位设为0,与ASCII码相同;而对于n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,其余空位由低到高地填充该字符unicode码,高位用0补足。
    UTF-8编码将英文字符编码为1字节,将汉字一般编码为3字节,相比直接存储unicode码点节约了空间。

    U+ 0000 ~ U+ 007F: 0XXXXXXX
    U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
    U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
    U+10000 ~ U+1FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
  • Windows默认使用GBK编码,而Linux系统默认使用UTF-8编码,不同系统间文件传输时需进行转码。

Python编码问题

  • 在Python内部,字符串(str)以unicode形式存在,即每一个字符存在对应的唯一的编号,ord(str)可以获取该编号(即为码点),chr(codepoint)可以获取编号对应的字符。

    >>> ord('a')
    97
    >>> ord('中')
    20013
    >>> chr(20013)
    '中'
    >>> '\u4e2d'
    '中'
  • 编码和解码
    Python的字符串(str)在内存中Unicode形式存在,如果需要在网络中传输或是存储在硬盘中,则要通过encode()编码成字节流(bytes)。同样,从网络或磁盘中读取到的字节流可以通过decode()解码成字符串。

    >>> 'ABC'.encode('ascii')
    b'ABC'
    >>> '中文'.encode('utf-8')
    b'\xe4\xb8\xad\xe6\x96\x87'
    >>> '中文'.encode('gb2312')
    b'\xd6\xd0\xce\xc4'
    >>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
    '中文'
  • 文件IO的编码问题
    Python可以使用open()打开文件,接收参数依次为文件路径打开方式(r/w),编码方式(encoding)。
    如果是读取文件,则encoding参数指定的是将文件内容解码(decode)为字符串str(unicode)所用的编码方式,此时encoding应与文件编码保持一致。
    如果是写入文件,则encoding指定的是将字符串(unicode)编码(encode)并存储于文件所用的编码方式。
    Python中打开文件,如果不指定encoding参数,则默认使用cp936,也就是我们熟悉的GBK编码。
posted @ 2017-12-12 13:48  zhayujie  阅读(97)  评论(0编辑  收藏  举报