讲明白编码乱码问题

在开发的过程中,在处理字符串输入输出的时候,经常会碰到乱码的问题。通常的解决方案,在百度或google上查一下,很快就能把问题解决了。对于其原理,并没有深究。这次,尝试着把编码问题理解清楚。

编码文件常见的一些词语有unicode,utf-8,gb2312,ASCII等,这些词语就是是什么含义,他们之间又有什么关系呢?

这需要从计算的发展开始说。

美国人发明了计算机。因为计算机只能处理数字,而人类的自然语言是字符,所以,需要设计一种方案,让计算机能够处理字符,于是就出现了编码。编码,即约定字符与特定数据的对应关系。例如约定0表示a,1表示b,2表示c,3表示d等等等等,当然,这里只是举个栗子,实际计算机中abcd的编码并不是1234哦。

计算以字节为基本单位,一个字节有8位,8位能够表示256个不同值,也就能编码256个不同的字符。这对于英语来说,够用了。英语主要是26个小写字母,26个大写字母,再加上9个数字,还有一些括号等号分号等符号,总数也不会超过256,所以,美国人发明了一套编码规范,在这套规范里,用一个字节来对所有字符进行编码,这套编码称为ASCII编码。

后来计算机技术传遍了世界。在汉语中,汉字的个数可是远超256个,使用一个字节肯定无法编码所有汉字了。所以就需要更多的字节,才能编码全部汉字。使用2个字节时,最多能编码65536个字符,这个数量对于常用字来说足够了。于是中国汉字的这套编码,称为GB2312编码。那么对于日语,汉语,阿拉伯语,德语呢,各个语言的字符数量不相同,所以,就都设计了自己的编码规范,于是,计算机世界里才有了这么多中编码。

那为什么会出现乱码呢?

因为编码规范多了,所以,计算机里的同一个数值,在不同编码中代表的字符就可能不同,例如48这个值,在ASICC中可能代表c,在gb2312中可能代码p,在日语编码中可能代表t。或者反过来说,同一个字符,在不同编码中的值是不相同的,比如在ASCII中,m的编码值为32,在gb2312中,m的编码值为31,等等。这样如果用一种编码方式保存的字符串,读取时用另一种编码来读,读出来的字符串可能就与原来的字符串不相同了。这种情况,只是字符串变成了另一个字符串,还没有出现乱码。那么,再想一步。如果一种编码的值,在另一种编码中,根本没有与该值对应的字符,那么,这种情况,就出现了乱码。

乱码的出现,归根到底,是不同编码之间转换时出现了对应不上的问题。那么,怎么解决呢?

后来就提出了unicode,统一编码,它试图把全人类的所有的语言的所有字符都编码进来,使用4个字符,可以编码65536*65536个字符,约43亿个字符,应该够用了。

unicode编码虽然大而全,但也有确定,就是它固定占用4个字节,比较浪费空间,其实,大多数使用情况涉及到的字符,并没有那么多。于是,为了优化unicode,又提出了utf编码,它使用动态长度的字节来进行编码,对于前面的一些字符,只用1个字节编码,1个字节编码用完了,就用2个字节编码后面的字符,等等等等。

This is the end.

猜你喜欢

转载自blog.csdn.net/li_canhui/article/details/84997995