编码问题一直困扰着我,每次遇到乱码或者编码问题,网上一查,问题解决了,但是实际的原理并没有搞懂,每次遇到,都是什么头疼。
决定彻彻底底的一次性解决编码问题。
1.为什么要编码
计算机的基本单元是字节,一个字节是8bit。一个字节的范围是0~255。
人类要表示的符号肯定比256个多,所以无法用一个字节来表示这个多的符号。
你想想,光汉字就有几千个。
要解决这个矛盾,有了一个新的数据结构:char。char也就是字符,最长16bit,最短为8bit。一个字符的最大长度是16bit。一个字符的范围是0~2的16次方。
所以一个char型的数据结构,可以表示这个地球上的所有字符。
但是计算机它不会为你改变啊,它的基本单元还是字节,8bit。所以如何把一个最长为16bit的char字符表示成为一个或者若干个8bit长的byte字节,
这个过程就需要编码。
2.如何翻译
各种语言交流,都需要经过翻译。一个长为16bit的char字符表示成为一个或者若干个8bit长的byte字节,
计算机中提供了很多翻译方式:ASCII,ISO-8859-1,GB2312,GBK,UTF-8,UTF-16
上面的几种编码方式都可以看成是字典,它们规定了转化的规则,按照这个规则就可以让计算机正确通过字节的来表示我们自己定义的字符char这种数据类型。
ASCII码:
ASCII码,总共128个。由于ASCII码只有128个,所以可以用一个8bit长的字节表示,也可以用一个16bit长的字符表示。
0~31表示的控制字符如换行,回车,删除等,32~126是打印字符,如大写字母,小写字母等。
ASCII码是单字节编码,也就是一个8bit长的char字符或者一个8bit的byte字符用一个字节来编码。
ISO-8859-1:
128个字符对于只使用英语的国家来说是够用了,但是对于那么西欧国家的语言来说就不够用了,因为他们国家的语言中,除了英语字母,还有其他的字符。
于是ISO组织在ASCII码基础上制定了一系列的标准来扩展ASCII码,它们是ISO-8859-1至ISO-8859-15。其中ISO-8859-1涵盖了大多数的西欧语言字符,
所以应用的最为广泛。
ISO-8859-1也是单字节编码,也就是一个8bit长的char字符用一个字节来编码。也就是扩展ASCII码之后的ISO-8859-1,总共可以表示256个字符。
GB2312:
GB2312的全称是《信息技术 中文编码字符集》,GB2312是双字节编码,也就是一个16bit长的char字符用两个字节来编码。
GB2312可以表示682个符号和6763个汉字。
GBK:
GBK的全称是《汉字内码扩展规范》,它的出现是为了扩展GB2312,以表示更多的汉字。
GBK是双字节编码,也就是一个16bit长的char字符用两个字节来编码。
GBK可以表示21003个汉字。
UTF-16:
说到UTF必须提到Unicode,ISO试图创建一个全新的超语言字典,世界上所有的语言都可以通过这个字典来相互翻译,而这就是Unicode。
UTF-16以及下面提到的UTF-8都是Unicode的不同实现形式。
UTF-16是双字节编码,也就是一个16bit长的char字符用两个字节来编码。
UTF-8:
UTF-16统一使用两个字节来表示一个字符,虽然在表示上非常简单,方便,但是也有缺点,有很多的字符用一个字节就可以表示了,但是使用两个字节来表示,造成了
存储空间的浪费。UTF-8则采用了一种变长的表示技术,每个编码区域有不同的字符长度。不同类型的字符可以由1~6个字节来表示。
UTF-8有如下的编码规则:
如果是一个字节长度的byte或者8bit长的char,最高位为0,则表示这是一个ASCII字符,UTF-8用单字节来表示。
如果一个字节以11开头,则连续的1的个数暗示这个字符的字节数。110XXXXX则表示这是char字符的第一个字节,这个char字符由两个字节组成,这个char字符16bit长,
UTF-8需要用两个字节或者更多字节来编码这个字符。
如果一个字节以10开头,表名这个字节不是char字符的第一个字节,前一个字节是这个char字符的第一个字节,也暗示这个char字符由两个字节组成,这个char字符16bit长,
UTF-8需要使用两个或者更多的字节来编码这个字符。
3.
原文:http://www.cnblogs.com/wangliyue/p/4553351.html