字符编码

几天前使用ksoap2从webservice上获取数据,但是获取得到包含有中文的数据有时候会出现乱码,在客户端无论怎样进行转码都无法解决乱码的问题

我使用ksoap2获取其他天气的webservice数据时又不会出现这种情况,后来才发现原来是发布webservice时没有统一编码,而我获取的天气数据他们

都是同一编码成UTF-8格式的。于是趁这个问题来彻底了解一下字符的编码格式。

首先请阅都这篇博客,他对字符编码格式的由来进行了详细的说明,大开眼界(真心佩服,文章写的真好,通俗易懂)

字符编码详解及由来(UNICODE,UTF-8,GBK)

下面我来梳理一下我对这篇博客的阅读:

Ascii编码的由来

计算机早期所要表示的东西不多,只用了一个字节来表示所要表示的东西,也就是最多只能表示256个字母,并且这256个没有用完,只从0编到了127

我们就把这个编码方式叫做ANSI的“Ascii”编码(American Standard Code for Information Interchange,美国信息互换标准代码),当时世界上都是使用这

种编码方式,但是后来由于计算机的发展,这256个表示位根本不够用,于是就出现了其他的编码方式。

中文GBK编码方式的由来

我们都知道单词都是由26个英文字母组成,但是汉字可不知26个,还没有包括一些其他的少数民族字符,很显然Ascii编码方式肯定是不够用的,于是

我们就自己创建了一套编码方式,同时为了兼容Ascii编码方式,我们规定:使用两个字节来表示字符,但是0-127这些表示位依然保持,只不过换成

是两个字节表示就是了,但是大于127的两个字节大小的数字就表示一个汉字,前面的一个字节称之为高字节,从0xA1到0xF7,后面一个直接称之为

低字节,从0xA1到0xFE,这样就可以大约组合出7000多个简体汉字了,同时我们还将一些其他的符号也编码进去了。这些字符我们统称为全角字符

相反那些少于127的Ascii码字符我们称之为半角字符。刚开始的这套方案我们称之为GBK2312,但是由于后来发现情况不对,因为汉字太多了(我们的

汉字数目可不止7000多个),发现码位还是不够用,于是就要求只要高字节大于127就表示是汉字的开始,而低字节不再要求大于127,这样就增加了

一些码位,于是这个扩展后的GBK2312被称之为GBK18030。这一系列汉字的编码标准我们称之为“DBCS”(Double Byte Charater set 双字节字符集)

在DBCS的标准里,最大的特点就是两个字节的汉字和一个字节的英文同时并存于一套编码方案中,编写程序时为了支持中文,必须时刻注意每个字节

的大小,如果这个字节的值大于127,那么就证明了一个双字节的字符即将出现,于是我们就慢慢记住了:一个中文字符等于两个英文字符。

 

UNICODE字符集的由来

了解了GBK之后,我们会有一个疑问,其他国家的字符用什么表示,如果他们创建一套字符集,那么就必然出现一个数字可以表示多个字符,那么计算

机怎么识别,于是后来就出现了ISO(国际标准化组织),他们采取了很简单的办法就是:废除所有的地区性编码方案,重新搞一个包括地球上所有字

符的编码方案,这套方案就叫做UCS “Universal Multiple-Octet Coded Character Set”也就是我们俗称的UNICODE。

这里请千万注意:UNICODE只是一套字符的编码标准,他只是规定了字符的二进制代码,至于具体这个字符由几个字节来表示或存储并没有规定,于

是就出现了这样的问题:计算机并不知道这个字符是用几个字节来存储的,那怎样进行读取呢?于是就出现了一套实现UNICODE的编码方式,也就是

规定了UINICODE字符是的二进制代码是以几个字节的形式进行存储的。UTF就是实现UNICODE的一种编码方式。(看了上面的那篇博客在讲UTF的

时候彻底被误导了,他的说法我觉得含糊不清,根本无法分辨UTF和UNICODE的区别)

 

UNICODE字符集的问题

由于UNICODE只是规定了字符的二进制代码,但是并没有规定字符的存储方式,所以就出现了有的字符只需要一个字节就能够进行存储,但是有的字符

却需要2个,3个甚至多个字节进行存储。如果强行规定每个字符必须使用2个或者4个字节进行存储那么必然会造成很大的浪费,所以造成的结果就是

1.出现了多种UNICODE存储方式,也就是一个二进制代码他有多种二进制格式来表示,比如:01这个二进制代码他可以使用两个字节或者多个字节来进

行存储。2.因为这些差异导致UNICODE很久都得不到推广,直到互联网的出现。

 

UTF编码方式的由来

由于互联网的普及导致人们强烈要求一种统一的编码方式,也就是不要再出现一个二进制代码可以有多种表示方式,而只能有一种。例如:01这个二进制

代码他要么使用一个字节进行存储,要么使用多个字节进行存储,而不能你使用一个字节,他使用多个字节进行存储。

UTF的最大特点即是:他使用了不定常的编码方式,即对不同的字符所存储的字节大小是不一样的。UTF8他可以使用1-4个字节在计算机存储中来表示一

个字符。他的编码规则为:1.对于当字节字符,字节第一位为0,后面7位为UNICODE码,因此对于英文字符,UTF8编码和Ascii码是相同的。2.对于多字

节字符,假如这个字符有n个字节,UTF8编码的第一个字节的前n位都为1,其余为零,后面字节的前两位都为10,剩下的全部为这个UNICODE码的二进

制代码。下面为UNICODE和UTF8的转码规则:

字符编码_第1张图片

 

高低字节的存储方式

在实际的存储当中,假如两个字节的字符,如:06FC,在实际的存中他是06在前还是06在后呢?也就是他存储的是06FC,还是CF06呢?怎样进行区分

呢在计算机文本中规定,如果一个文本的开头为:FEFF,则这个字符的高位在前,即06FC的实际存储方式为:FC06,如果一个文本的开头为FFFE,则

这个字符的高位在后,即06FC的实际存储方式为:06FC。

 

联通这两个字保存后乱码的原由

我们在文本文档中输入中文,CTR + s的默认保存方式是GBK方式,联通两个字的内码为:

联——c1aa -11000001 10101010

通——cda8 -11001101 10101000

我们可以看到他们刚好符合UTF8的编码规则,于是当再次打开文档时程序就会将其默认为UTF8的编码,于是按照UTF8的方式去解码,但是在解码的过程

中发现在UTF8的编码规则中不存在此字符于是就以乱码的形式出现。

强烈建议阅读完上面一篇文章后,再阅读下面这篇博客,你会对字符编码有更深的体会(上面那篇博客有些问题并没有说清楚,如:UTF和UNICODE的联

系:字符编码笔记:ASCII,Unicode和UTF-8    Windows 记事本的 ANSI、Unicode、UTF-8 这三种编码模式有什么区别

「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别?网页代码一般使用哪个 好东西太多了赶紧收藏。

 

其余的扩展阅读

我们国家先后搞过三套汉字编码标准,既GB2312、GBK 和 GB18030。

http://shanks.my.phpcloud.com/?p=274

http://www.laruence.com/2009/08/22/1059.html

http://blog.csdn.net/stilling2006/article/details/4129700

http://www.joelonsoftware.com/articles/Unicode.html

字符集知识普及

 

你可能感兴趣的:(字符编码)