zoukankan      html  css  js  c++  java
  • 编码&解码

    编码与解码
    首先,明确一点,计算机中存储的信息都是二进制的

    编码/解码本质上是一种映射(对应关系):
    比如‘a’用ascii编码则是65,计算机中存储的就是00110101,但是显示的时候不能显示00110101,还是要显示'a',

    但计算机怎么知道00110101是'a'呢,这就需要解码,当选择用ascii解码时,当计算机读到00110101时就到对应的ascii表里查看发现是'a',就显示为'a'

    编码(encode):文本字符与二进制串的对应关系,文本字符 ——> 二进制串
    解码(decode):二进制串与文本字符的对应关系,二进制串 ——> 文本字符


    1.为了处理英文字符,产生了ASCII码
    2.为了处理中文字符,产生了GB2312
    3.为了处理各国字符,产生了Unicode
    4.为了提高Unicode存储和传输性能,产生了UTF-8,它是Unicode的一种实现形式


    ASCII & UTF-8
    大家熟知的ASCII以1字节(8个bit)表示一个字符,首位全是0,表示的字符集明显不够用

    unicode编码系统是为表达任意语言而设计的,为了防止存储上的冗余(比如,对应ascii码的部分),其采用了变长编码,
    但变长编码给解码带来了困难,无法判断是几个字节表示一个字符.

    UTF-8是针对unicode变长编码设计的一种前缀码,根据前缀可判断是几个字节表示一个字符

    Unicode符号范围 | UTF-8编码方式
    0000 0000 ~ 0000 007F | 0xxx xxxx
    0000 0080 ~ 0000 07FF | 110x xxxx 10xx xxxx
    0000 0800 ~ 0000 FFFF | 1110 xxxx 10xx xxxx 10xx xxxx
    0001 0000 ~ 0010 FFFF | 1111 0xxx 1110 xxxx 10xx xxxx 10xx xxxx


    如果一个字节的第一位是0,则这个字节单独就是一个字符;
    如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。


    比如"严"的unicode是4E25(100111000100101),4E25处在第三行的范围内(0000 0800 ~ 0000 FFFF),
    因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。
    然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,高位补0:

    1110xxxx 10xxxxxx 10xxxxxx
    0100 111000 100101 #最前面补一个0
    11100100 10111000 10100101

    得到"严"的UTF-8编码是"11100100 10111000 10100101"。


    python中的解码和编码

    在python中,编码解码其实是不同编码系统间的转换!!!!
    默认情况下,转换目标是Unicode,即编码unicode —— >str,解码str ——> unicode,其中str指的是字节流

    而str.decode是将字节流str按给定的解码方式解码,并转换成utf-8形式,
    u.encode是将unicode类按给定的编码方式转换成字节流str

    注意:
    调用encode方法的是unicode对象生成的是字节流,即编码
    调用decode方法的是str对象(字节流)生成的是unicode对象,即解码

    若str对象调用encode会默认先按系统默认编码方式decode成unicode对象再encode,忽视了中间默认的decode往往导致报错!!!!!

    简单的来说:
    decode()方法将其他编码字符转化为Unicode编码字符
    encode()方法将Unicode编码字符转化为其他编码字符


    在Python中有两个和字符很相关的类型: 一个是str类型,一个是unicode类型

    这两种类型的对象都是sequece序列,其中str是字节序列,而unicode是字符序列

    decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
    encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。


    示例如下:
    >>> a = '中国'
    >>> a
    'xe4xb8xadxe5x9bxbd' #可以看出a是utf-8编码(每个汉字占3个字节)
    >>> b = a.decode('utf-8') #将utf-8编码的字符转换(解码)为Unicode编码
    >>> b
    u'u4e2du56fd' #可以看出b是Unicode编码的字符串,最前面有字符u
    >>> c = b.encode('gbk') #将Unicode编码的字符,转换(编码)为gbk编码
    >>> c
    'xd6xd0xb9xfa' #gbk编码的字符串每个汉字占用2个字节

    >>> d = a.encode('gb2312') #直接将utf-8编码的字符转换为gb2312编码,报错
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
    >>>

    由上述可知,decode()方法可以将任何编码的字符,转换为Unicode编码
    而如果想从编码1转换为编码2,必须先将编码1转换(解码)为Unicode编码,然后才能转换(编码)为编码2 (针对python 2.x)


    python2.7中的字符串:

    unicode ——》编码encode('utf-8') ——》写入文件

    读出文件 ——》解码decode('utf-8') ——》unicode


    在使用unicode的时候,必须注意以下的原则:

    1、程序中出现字符串的地方加前缀u,表示为unicode类型

    2、不要使用str函数,在使用的时候使用unicode函数

    3、不要使用string模块

    4、只有在写入文件或者数据库或者网络的时候,才使用encode函数来进行编码发送;只有在把数据读取回来的时候,才使用decode进行解码


    在使用读写unicode数据库的时候,注意几个方面:

    1、数据库服务器,例如mysql,只要每个表使用utf-8格式来进行编码即可

    2、数据库适配器,例如mysqldb,在connect()方法中使用use_unicode方法

    3、web开发框架,例如django,进行更多的设置


    自己写代码时只需记住str字节流调用decode,unicode对象调用!!!!!


    s = u'严' #定义了一个unicode对象(不是utf8)
    s #输出u'u4e25'
    print type(s), s #输出<type 'unicode'> 严


    u = s.encode('utf8') #用s.encode('utf8'),则将s使用utf-8编码并将编码结果保存为字节流
    u #输出'xe4xb8xa5'
    print type(u),u #输出<type 'str'> 涓

    还有要注意的是,终端默认的编码格式是gbk,windows cmd中可以通过chcp查看以及改变,也可以到注册表修改终端默认编码(HKEY_CURRENT_USER console或者powershell下的codepage),936为简体中文,65001为utf8,两者都可显示中文,但为了方便中文输入,我将其默认设为936


    当调用print函数将内容格式化输出到终端时,会将unicode对象转换为终端的编码方式输出 !!!!!
    如上面第一次print的结果是正常的,print utf8字节流时,终端按其默认gbk解码显示时就会出问题,这里恰巧'xe4xb8'为gbk下的“涓”

    t = s.encode('utf8').decode('utf8')
    t #输出u'u4e25'


    文件的编码格式
    保存文本时也有编码格式,比如txt文件保存可选择则ASCII、utf8等,对py文件可在前两行注明编码方式# -*- coding: UTF-8 -*-

    在python中读取文件
    fr = open('encode.py','r')
    fstr = fr.read()

    只要记住fstr是字节流,其他的操作参看上面即可

    注:以上操作均在cmd或powershell下完成,在python自带的解释器下会有问题,s=u'你好',然后s,显示的虽然是unicode对象,但是编码却是gbk的而不是unicode

  • 相关阅读:
    解决无法安装Microsoft .Net Framework 3.5
    day11-15,装饰器
    Xmanager Power Suit 6.0.0009 最新版注册激活
    eth
    MySql 8.0 版本使用navicat连不上解决
    day11
    Mybatis使用规则
    nginx的基本配置
    Mybatis分页插件PageHelper使用
    dubbo的使用
  • 原文地址:https://www.cnblogs.com/wyzhou/p/9589325.html
Copyright © 2011-2022 走看看