ASCII,ANSI,Unicode,UTF-8各种编码方法解析

来源:互联网 发布:怎么从ims查数据 编辑:程序博客网 时间:2024/06/05 19:47

1. 字符集与编码:

1.1 字符集

 使用哪些字符。也就是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“**字符集**”。

1.2 编码

规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“**编码**”。

各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:ASCII,ANSI(GB2312, GBK, JIS),Unicode 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。

2. 字符与编码的发展

从计算机对多国语言的支持角度看,大致可以分为三个阶段:

阶段 系统内码 说明 系统支持 阶段一 ASCII 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示 英文DOS 阶段二 ANSI编码(本地化) 为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 ‘中’ 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 中文 DOS,中文 Windows 95/98,日文 Windows 95/98 阶段三 UNICODE(国际化) 为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 Windows NT/2000/XP,Linux,Java

3.名词解释

3.1. ASCII

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言。它是现今最通用的单字节编码系统

3.2 ANSI

ANSI(American National Standards Institute),为使计算机支持更多语言,通常使用 0x80~0xFF 范围的多个字节来表示 1 个字符。比如:汉字 ‘中’ 在简体中文Windows操作系统中,使用 [0xD6,0xD0] 这两个字节存储。对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。这一点是ANSI编码与UTF-16编码之间最大也最明显的区别。比如“A君是第131号”,在ANSI编码中,占用12个字节,而在UTF-16编码中,占用16个字节。因为A和1、3、1这4个字符,在ANSI编码中只各占1个字节,而在UTF-16编码中,是需要各占2个字节的,至于简体中文编码GB2312,实际上它是ANSI的一个代码页936

字符内码(charcter code):指的是用来代表字符的内码.读者在输入和存储文档时都要使用内码,内码分为

  • 单字节内码 :Single-Byte character sets (SBCS),可以支持256个字符编码.
  • 双字节内码:Double-Byte character sets)(DBCS),可以支持65000个字符编码.
    前者即为ASCII编码,后者对应ANSI.

3.3 Unicode

Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是“Universal Multiple-Octet Coded Character Set”,简称为UCS。UCS可以看作是”Unicode Character Set”的缩写。

一般采用UCS-2 方案,即一种2字节编码,能够提供65536个字符,这个数字是不够表示所有的字符的(汉语就有55000多字符),所以,通过一个代理对的机制来实现附加的917,476个字符表示,以达到所有字符都具有唯一编码.

“UNICODE 字符集”包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

3.3.1 Unicode解析

需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字“严”的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题,第一个问题是,如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:
1. 出现了unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。
2. unicode在很长一段时间内无法推广,直到互联网的出现。

3.3.2 字节序(endian)

字节序:顾名思义就是字节存放的顺序
字节序分为两种:

  • big-endian(大端字节序):高字节存于内存低地址;低字节存于内存高地址(内存的地址是由低到高的顺序;而数据的字节却是由高到低的,故以上字节序是大端字节序);
  • little-endian(小端字节序):低字节存于内存低地址;高字节存于内存高地址(内存的地址是由低到高的顺序;而数据的字节也是由低到高的,故以上字节序是小端字节序)。

常说的低位在先,高位在后。

JAVA字节序::指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。

主机字节序 :Intel的x86系列CPU是Little-Endian,而PowerPC 、SPARC和Motorola处理器是BIG-ENDIAN。

ARM同时支持 big和little,实际应用中通常使用little endian。是BIG-ENDIAN还是LITTLE-ENDIAN的跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN。

网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序(BIG-ENDIAN)。 TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序。

不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。

处理器     操作系统   字节排序Alpha     全部        Little endianHP-PA     NT          Little endianHP-PA     UNIX        Big endianIntelx86  全部        Little endian

3.3.3 各种Unicode编码

Unicode: 通常指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode编码。这个选项用的little endian格式。
Unicode big endian编码:与上一个选项相对应
UTF-8编码:一种针对Unicode的可变长度字符编码

Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?

我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)

3.4 UTF-8:

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。

3.4.1 UTF 编码

事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)。常见的UTF格式有:UTF-7, UTF-7.5, UTF-8,UTF-16, 以及 UTF-32。
如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节。而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。

UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围 | UTF-8编码方式(十六进制) | (二进制)--------------------+---------------------------------------------0000 0000-0000 007F | 0xxxxxxx0000 0080-0000 07FF | 110xxxxx 10xxxxxx0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

下面,还是以汉字“严”为例,演示如何实现UTF-8编码。

已知“严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,转换成十六进制就是E4B8A5。

4. 参考文献

参考文献1:http://www.regexlab.com/zh/encoding.htm
参考文献2:http://blog.csdn.net/xiongxiao/article/details/3741731
参考文献3:http://blog.csdn.net/lvxiangan/article/details/8151670
参考文献4:http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html

0 0