编码&解码
编码与解码
首先,明确一点,计算机中存储的信息都是二进制的
编码/解码本质上是一种映射(对应关系):
比如‘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
'\xe4\xb8\xad\xe5\x9b\xbd' #可以看出a是utf-8编码(每个汉字占3个字节)
>>> b = a.decode('utf-8') #将utf-8编码的字符转换(解码)为Unicode编码
>>> b
u'\u4e2d\u56fd' #可以看出b是Unicode编码的字符串,最前面有字符u
>>> c = b.encode('gbk') #将Unicode编码的字符,转换(编码)为gbk编码
>>> c
'\xd6\xd0\xb9\xfa' #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 #输出'\xe4\xb8\xa5'
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解码显示时就会出问题,这里恰巧'\xe4\xb8'为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
编码&解码的更多相关文章
- C# base 64图片编码解码
使用WinForm实现了图片base64编码解码的 效果图: 示例base 64编码字符串: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKD ...
- java中文乱码解决之道(五)-----java是如何编码解码的
在上篇博客中LZ阐述了java各个渠道转码的过程,阐述了java在运行过程中那些步骤在进行转码,在这些转码过程中如果一处出现问题就很有可能会产生乱码!下面LZ就讲述java在转码过程中是如何来进行编码 ...
- java中文乱码解决之道(六)-----javaWeb中的编码解码
在上篇博客中LZ介绍了前面两种场景(IO.内存)中的java编码解码操作,其实在这两种场景中我们只需要在编码解码过程中设置正确的编码解码方式一般而言是不会出现乱码的.对于我们从事java开发的人而言, ...
- Unicode编码解码在线转换工具
// Unicode编码解码在线转换工具 Unicode 是基于通用字符集(Universal Character Set)的标准来发展,并且同时也以书本的形式(The Unicode Standar ...
- .NET编码解码(HtmlEncode与HtmlEncode)
编码代码: System.Web.HttpUtility.HtmlEncode("<a href=\"http://hovertree.com/\">何问起& ...
- sed处理url编码解码=== web日志的url处理
URL 编码/解码方法(linux shell实现),方法如下: 1.编码的两种方法: admin@~ 11:14:29>echo '手机' | tr -d '\n' | xxd -plain ...
- ASP.NET中Url编码解码
今天遇到Url编码解码的问题,纠结了一天的时间,结果上网一查才发现太二了我们. 同事写的代码把url用HttpUtility.UrlEncode编码和解码了,本地测试没有问题,部署到服务器上就提示转码 ...
- C++ Base64 编码 解码
C++实现 base64 字符串编码解码(GCC编译). /** * @brief C++ base64 编解码 * @author wid * @date 2013-20-25 * * @note ...
- 理解netty对protocol buffers的编码解码
一,netty+protocol buffers简要说明 Netty是业界最流行的NIO框架之一优点:1)API使用简单,开发门槛低:2)功能强大,预置了多种编解码功能,支持多种主流协议:3)定制能力 ...
- 用jq编码解码一个url地址
介绍一下编码解码函数对 1. escape /unescape 主要用于汉字编码,返回字符的unicode编码值, 对“+”不能编码 2. encodeURI / decodeURI ...
随机推荐
- POJ1458【最长公共子序列】
基础DP. #include <iostream> #include <stdio.h> #include <string.h> #include <stac ...
- POJ2533/hdoj1950【DP】
O(nlog(n))的方法: 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素. d中元素也是单调递增的. #include <iostrea ...
- chrome调试中resource改到application中了
如题,看视频的时候发现在resource下面查看cookie,但是自己试的时候发现没有了这个工具, google之后发现原来该位置了
- hdu1879 继续畅通工程 基础最小生成树
#include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> u ...
- 无法获得VMCI 驱动程序的版本: 句柄无效的解决方法
关闭虚拟机,找到安装路径,用记事本打开.vmx结尾的文件 将vmci0.present = "TRUE"改为vmci0.present = "FALSE"保存
- The 17th Zhejiang University Programming Contest Sponsored by TuSimple J
Knuth-Morris-Pratt Algorithm Time Limit: 1 Second Memory Limit: 65536 KB In computer science, t ...
- 抽象类 abstract
抽象类就是拿来继承的抽象方法就是拿来重写的 1.用abstract可以用来修饰类或方法,分别叫抽象类和抽象方法. 2.含有抽象方法的类必须被声明为抽象类.,抽象类必须被继承,抽象方法也必须被重写. 3 ...
- 502 IPO 上市
详见:https://leetcode.com/problems/ipo/description/ C++: class Solution { public: int findMaximizedCap ...
- UESTC - 878 温泉旅店 二维费用背包问题
http://acm.uestc.edu.cn/#/problem/show/878 设dp[i][j][k]表示在前i个数中,第一个得到的异或值是j,第二个人得到的异或值是k的方案数有多少种. 因为 ...
- MySQL5.5升级到5.6
5.6的新的特性 .支持GTIDs,Failover.多线程复制. 新增binlog_row_image只记录row格式下所用字段的修改(而不是像以前一样记录全部列),节省空间等资源: master. ...