ASCII和Unicode编码详解
来源:互联网 发布:初中数学答题软件 编辑:程序博客网 时间:2024/05/29 16:05
本文参考大量维基百科和网络大牛的文章,并结合实际例子,试图帮助大家理清计算机的编码问题,从而更加高效的编写程序。
一. 知识补充
1.1 位
我们常说的位是指比特位,即bit,每一个bit位存储一个0或者1。所以,在计算机(二进制数系统)中,一个位(bit)就是指一个0或者1。我们说计算机的CPU一次能处理的最大位数就是指这个位。
1.2 字节
字节(Byte)是指一小组相邻的二进制数码,每8个位组成一个字节,即1Byte = 8bit。我们通俗的说,8个0或者1组成一个字节。字节是计算机基本的信息存储和处理单位。
二. ASCII
ASCII是由美国制定的标准单字节字符编码方案,主要用于显示现代英语。标准ASCII码使用7位二进制数来表示所有的大写和小写字母、数字0~9、标点符号和特殊控制字符,共计128个字符,具体可以参照ASCII对照表查看。
在标准的ASCII中,最高位(b7)用作奇偶校验位。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验道理相似。
由于标准ASCII字符集字符数目有限,无法满足需求,国际标准组织在兼容的前提下,将ASCII字符集扩充为8位代码的统一方法,后面补充的这128个字符编码就称为扩展ASCII码。
三. Unicode
Unicode和UCS的详细区别请google。
前面说到8位ASCII远远不能满足所有字符的编码需求,怎么办?增加二进制表示的位数。最初版本的unicode字符编码采用16位,这样就能表示65536个码位,此版本也称UCS2。这对于表示世界上大多数的语言、字符已经是充裕的了。
但是为什么说只是充裕的?因为这些组织在制定这些字符集的时候就想了,如果有一天,外星人来到地球,并带来了新的语言或符号,或者我们人类进化,某个种族突然创造出一种新的语言怎么办?好吧,在16位的基础上再加16位,现在32位,够了吧?这就是UCS-4版本,UCS-4是一个更大的32位字符集,最高位恒为0,可以表示2^31个字符,这样足够了,但是实际并非如此。
在UCS4中,所有的编码空间被分为17个平面,每个平面包含2^16个码位。第一个平面称为基本多语言平面(BMP),也称第0平面,与我们现在实际中用的UCS-2编码相同,BMP使用16位的编码空间,码位从U+0000到U+FFFF,包含了我们常用的字符。
到这里,我们已经把全世界有的没有的语言、符号都赋予了一个唯一的二进制码位。似乎是没问题了,但是美国不同意了,为什么?因为我们前面说美国制定的ASCII编码,只用一个字节就能表示他们用到的所有大小写字母、字符等,为什么要换成占用两个字节unicode?而且高字节的八个位都是0,这样对存储空间和传输空间都是浪费。为了解决这个这个问题,UCS字符U+0000到U+007F被编码为字节0X00到0X7F,只占用1个字节,这样unicode便与ASCII兼容了。
下面我们举例演示unicode编码:
A à \u41
朕 à \u6715
字母A的unicode编码是\u41,1个字节,转换二进制是 0100 0001,和A的ASCII码一致。
中文“朕”的unicode编码是\u6715,2个字节,转换二进制是
01100111 0001 0101,
unicode的工作是制定了类似“朕”与0110 0111 0001 0101之间唯一的映射。
四. Unicode实现方式UTF
Unicode是一个字符集,收录的字符和编码是唯一对应的,它只规定了如何编码,并没有规定如何保存、传输这个编码。所以我们说unicode只完成了一半的工作,还需要定义一种方法来确定码位在内存和硬盘中如何表示,unicode标准为此定义了几种映射,称为unicode转换格式,简称UTF。
1. UTF-32
我们首先介绍UTF-32,UTF-32是最清楚的,但是使用最少的一个。为何?每一个码位使用整32位,因此每一个UTF-32值都可以直接表示对应的码位。然而,UTF-32几乎从来没在实际中使用过,因为每个字符占用4个字节,这样就太浪费空间了。
2. UTF-16
前面我们说到Unicode编码空间被划分为17个平面,每个平面包括65536个码位。第一个平面称为基本多语言平面,简称BMP,其它平面称为辅助平面。
在BMP中,从U+D800到U+DFFF之间的码位区段是永久保留不映射的字符,UTF-16就是利用保留下来的这个区段码位来映射辅助平面的字符的码位。
3. UTF-8
UTF-8使用1-6个字节为每个字符编码:
一个字节编码128个ASCII字符(U+0000---U+007F);
二个字节编码拉丁文等附带符号的其它字符(U+0080---U+07FF);
三个字节编码BMP中的其它字符,包括中文;
四~六个字节编码unicode辅助平面的字符。
UTF-8的编码规则:
1)单字节符号,最高位为0,后面7位为这个符号的unicode码,因此一个字符表示的UTF-8编码与对应的ASCII码是相同的;
2)N(N>1)字节符号,最高字节的前N位全为1、第N+1位为0,后面字节的前两位为10,所有字节剩余的位,由符号的unicode码补充。
下面举例演示UTF-8的编码规则:
a) 中文“朕”是BMP中的字符,编码为UTF-8使用3 个字符,根据UTF-8的编码规则2,首先我们我三字节的框架搭好:
1110xxxx 10xxxxxx 10xxxxxx
b) 查到朕的十六进制unicode编码是\u6715,转换为二进制代码是
01100111 00010101
c) 将这串二进制代码填充空余处(如颜色示意):
01100111 00010101
1110xxxx 10xxxxxx 10xxxxxx
11100110 10011100 10010101
d) 将上述的二进制字符串转换为16进制就是
\xe6\x9c\x95
五. 中文编码
1. GB2312字符集
GB2312是中国规定的汉字编码,也可以说是简体中文的字符集编码,共收录6763个汉字和682个字符,每个汉字及符号以两个字节来表示
2. GBK
GBK是GB2312的扩展,除了兼容GB2312外,还收录了中文繁体、日语中的一些字符。
六. 混淆点
1. UTF不是一种编码,只是unicode编码的一种储存和传送格式
Unicode\GBK\GB2312是编码字符集
2. UTF-8码完全针对unicode,如果GBK要转为UTF-8,必须先转为unicode码,然后才能转为UTF-8,反之一样。
七. Python的编码问题
1. python 2.x编码问题根源
Python2.x版本编写的程序默认采用ASCII编码,这个通过sys模块便能直接看到看到。
Import sys
Print sys.getdefaultencodeing()
根据上面我们对ASCII的编码格式分析,ASCII只能识别包含大小写英文字母、特殊字符个标点符号在内的128个字符,那么问题就来了,如果在我们的代码中使用了某些个超出ASCII编码范围的字符,比如中文,python解释器就不能识别这个特殊的字符,所以会报出了如下的错误:
UnicodeDecodeError:'ascii' codec can't decode byte 0x?? in position x: ordinal not in range(128)
初期python使用者最常见的一个异常,其根本原因就在于此。
- ASCII和Unicode编码详解
- ASCII和Unicode编码
- ASCII编码 和 UNICODE编码
- ASCII编码和Unicode编码
- ASCII、Unicode和UTF-8编码知识详解
- ASCII,Unicode和UTF-8字符编码详解
- ASCII和unicode编码区别
- ASCII编码和UNICODE、utf-8编码
- ASCII编码和UNICODE编码转换
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- 字符编码:ASCII,Unicode和UTF-8
- day59,page80
- [命令技巧]mkdir -p
- poj 3255 Roadblocks
- Raspberry - 挂载U盘
- 使用putty起vncserver
- ASCII和Unicode编码详解
- 实现键值对存储(三):Kyoto Cabinet 和LevelDB的架构比较分析
- 申请了一张招行的全币种信用卡
- UI第一节课
- meta标签
- Dongle烧写模块重构(六)--单模块单功能下的命令模式尝试
- Formidable文件上传
- uploadify上传注意
- 4-07. 修理牧场(25) (ZJU_PAT 优先队列)