最近公司新入职了很多小伙伴~ 现整理一些常用到的编码知识点,帮助小伙伴绕坑远行~
一、字符编码由来
我们知道计算机内部只能处理0和1,也就是二进制编码。我们熟知的磁盘文件其实是操作系统对计算机内部存储的一种抽象封装,方便应用程序读取以及人们交流。磁盘文件中的内容需要转换为数字,以二进制方式存储,才能被计算机处理。
由于每个二进制由0和1表示,最早计算机设计采用8个比特(bit)作为一个字节(byte),也就是8位二进制,所以一个字节能表示最大十进制整数255(1111 1111)。
所有的文件是以字节序列的方式储存,计算机系统内部所有信息,包括磁盘文件、内存中的数据以及网上传送的数据,都是由一串比特表示。
1. 计算机文件
计算机文件基本上分为二种:二进制文件和文本文件。从本质上来说他们之间没有什么区别,因为他们在硬盘上都有一种的存放方式--二进制。
文本文件:一种由很多行字符构成的计算机文件,可以用任何文字处理程序阅读的简单文本文件。
二进制文件:图形文件及文字处理程序等计算机程序都属于二进制文件。
2. 字符编码
ASCII字符集
美国制定了一套字符编码,将英文字符一一映射到二进制编码上,这就是ASCII码字符集(American Standard Code for Information Interchange,美国信息互换标准代码)。ASCII字符集一共规定了128个字符的编码,包括常见的英文字符、数字字符以及32个控制符号等,比如,A是指65(二进制 0100 0001)。这些符号只占用了一个字节的后7位,第一位统一设为0。
其他字符集
英文字符用128个符号编码满足需求,但是对于中文字符(汉字就有10万左右)或者日文远远不够,所以不同国家制定了自己的字符集。比如,简体中文常见的编码方式是gb2312,使用两个字节表示一个汉字,理论上最多表示255x255=65536个。日本使用Shift_JIS编码,韩国使用Euc-kr编码。但不管怎样,0-127表示的符号统一的,不同的只是其他位。
Unicode字符集
根据以上所说,现存在多种编码方式,如果要打开一个文件,就需要知道文件的编码方式,否则导致乱码,这就使得显示其他编码方式的字符很不方便。
Unicode(Universal Multiple-Octet Coded Character Set)是一个可以容纳100多万个符号的字符集,支持多个国家的字符编码,它将ascii码里的字符长度扩展为16位,编码不变。但这样就会导致两个问题:
一是计算机读文件时不确定字节长度。
二是对于ascii字符而言,极大地浪费存储空间。
UTF-8编码
UTF-8(UCS Transfer Format-8)是在互联网上使用最广的一种unicode的实现方式,每次传输8个位,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上的字符了,当然还有UTF-16、UTF-32等。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,注意的是unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节。
unicode转换utf-8
从unicode到utf-8需要一些规则来转换,如下。
1. 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;
2. n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码,高位用0补足。
Unicode符号范围 UTF-8编码方式
(十六进制) (二进制)
—————————————————————–
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
二、常见的编码问题(python2.7)
1. 指定编码格式
python文件默认是以ascii编码,所以当文件中出现中文时,需要指定编码方式为"utf-8",在文件头加上"#coding:utf-8"。如果文件中全部是英文,那就无需指定,因为英文的两种编码方式没有差别。
python文件默认以ascii方式进行解码,需要指定解码方式。
import sys reload(sys) sys.setdefaultencoding("utf-8")
2. 常见的编码转换
(1) str2 = str1.decode("本身的编码方式").encode("目标编码格式")
(2) 常用的方法
ord( )函数获取字符的十进制整数表示,chr( )函数把十进制整数转为对应的字符,hex( )函数将字符对应的整数表示转为十六进制
3. 约定俗成
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,转换为utf-8编码。用记事本编辑时,从文件读取的UTF-8字符被转换Unicode字符到内存中,编辑完成后,保存的时候再转换为utf-8文件。浏览网页时,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。
4. 中文显示方式
1) import uniout
# coding:utf-8 import uniout s = {"hello":"你好"} print(s)
输出{'hello':'你好'}
2) 也可以借用 json.dumps(str, ensure_ascii=False)
参考链接:
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
https://www.zhihu.com/question/23374078