对ASCII、Unicode、UTF-8、GB2312的理解

时间:2023-01-06 15:53:22

最近看werkzeug,代码涉及到很多编码格式的转换问题,由于对一些主流的编码格式不是太懂,特意花时间仔细的看了看。

ASCII

ASCII是计算机刚刚实现的60年代,由美国ANSI标准协会制订的,通过8位表示的字符集。最初只用前128个数值表示字符,最高位为0;后来为了收录更多的字符,就将128~255的字符也用于表示字符,自此一个套完整的ASCII编码体系就出来了。因为只要一张字符和对应的8比特数据相对应的表,就可以解决字符的存储问题,所以当时计算机的编码、解码很简单,只要将字符对应的8比特数据输入计算机就可以了。

GB2312

因为ASCII码只用8个比特位表示字符,最多只能表示255个字符,不能解决汉字的编码问题。那么中国在80年代就自行开发了GB2312编码体系,这个体系用16位两个字节表示一个字符,称为双字节字符集(DBCS, double byte charactor sets)。这个字符集,根据第一个字节最高位的比特数值,寻找相应的码表,然后在码表里面找到相应的字符。后来在GB2312的基础上右扩展了字符集叫GBK以及GB18030

Unicode

因为不同国家对各自国家的语言所用的编码规则不同,那么要在同一个文件中输出不同编码规则的文字,由于计算机不知道要用哪一种编码规则解码这些比特流,那么就会出现乱码。为了解决全世界文字的兼容问题,就出现了Unicode字符集合,最新的字符集用0x10FFFF包含所用的字符,10转换成十进制为17对应表示字符的17个平面,FFFF转换成十进制为65536,表示每一个平面内能够容纳65536个字符,这是一个巨大的字符集合。完全可以用第一个平面65536个编码位置,表示所用的字符集,将第一个平面叫做BMP(多文种基本平面),目前主流都是用的这个平面的字符集。

针对Unicode字符集,出现了不同的编码解码方法,比方说UCS-2,UCS-4,UTF-8,UTF-16。注意Unicode只是表示字符对应的编码,而UCS-2,UTF-8是对Unicode的编码进行计算机存储和传输的方式

UCS-2是用两个字节存储Unicode码,由于其只能表示BMP平面上的字符,不能表示其他平面上的字符,具有一定的局限性。所以出现了UTF-16,这个编码方法,最少采用2个字节,为了表示其他字符平面的数值,采用4个字节配对。

UTF-8
与UCS-2、UTF-16对Unicode的编码解码方式不同,UTF-8采用了更加聪明的方式进行编码解码,规则如下图:
对ASCII、Unicode、UTF-8、GB2312的理解
从上图可以看出:

对于ASCII字符的编码使用单字节,和ASCII编码一摸一样,这样所有原先使用ASCII编解码的文档就可以直接转到UTF-8编码了。对于其他字符,则使用2-4个字节来表示,其中,首字节前置1的数目代表正确解析所需要的字节数,剩余字节的高2位始终是10。例如首字节是1110yyyy,前置有3个1,说明正确解析总共需要3个字节,需要和后面2个以10开头的字节结合才能正确解析得到字符。

UTF-8GBK的关系

GBK和UTF-8都要经过Unicode进行转化
GBK、GB2312 ——> Unicode ——>UTF-8
UTF8——>Unicode ——>GBK、GB2312
以上是对于各种编码体系的理解,主要参考:
http://blog.csdn.net/hherima/article/details/8655200
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
http://jsfox.cn/blog/others/quick-translate-chinese-utf8-by-unicode.html
http://www.imkevinyang.com/2009/02/%E5%AD%97%E7%AC%A6%E7%BC%96%E8%A7%A3%E7%A0%81%E7%9A%84%E6%95%85%E4%BA%8B%EF%BC%88ascii%EF%BC%8Cansi%EF%BC%8Cunicode%EF%BC%8Cutf-8%E5%8C%BA%E5%88%AB%EF%BC%89.html
http://www.imkevinyang.com/2010/06/%E5%85%B3%E4%BA%8E%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%EF%BC%8C%E4%BD%A0%E6%89%80%E9%9C%80%E8%A6%81%E7%9F%A5%E9%81%93%E7%9A%84.html