首页 > 代码库 > 【白话篇】10分钟搞懂字符编码

【白话篇】10分钟搞懂字符编码

如上图所示为常见的,让人看了头晕的 几个种编码。 看懂下面几条规则,你就明白他们的关系了。

【1】有些人说,GBK严格来说是字符集,而utf-8则是编码,这种区分已经相当模糊了,他们都是“字节到字符的映射关系”,所以下面都用编码来说吧。

【2】 ISO-8859-1 这种编码是单字节编码,衍生于ASCII,表示范围0~255,只要按照ASCII的规则设计的编码,不管是几字节的,都可以和ISO-8859-1兼容。

【3】比如说,GBK编码(双字节)能转化成ISO-8859-1编码,是因为GBK的每个字节和ISO-8859-1不冲突,即不会存在一个GBK的编码 设为XX YY,其中XX YY是ISO-8859-1已经定义的英文字符,由于ISO-8859-1衍生从ASCII,常见的单字节字符用0~127表示了,那么GBK等编码在设计的时候就应该避免单字节的值位于[0,127]之间,否则编码将会无法区分到底这个字节是双字节编码的一部分,还是一个完整的单字节编码。这就是所谓的兼容。 

【4】上面这几种里,就Unicode没有给ISO-8859-1和ASCII编码面子,一位都不放过,用双字节定义了几乎所有的字符。它为什么可以做到这一点?因为对于 ‘a’这个字符,它也使用了两个字节来编码,这样,解码的时候就 双字节 双字节的读出来,然后解码。

【5】严格意义上来说,ISO-8859-1不能算是一种中文编码,对它来说,存储都是单字节的。它无法作为一种中文编码单独存在。它只和那些尊重ASCII已有单字节编码规则的多字节编码相互转换。

【6】关于GBK和utf-8 能否互相转换的问题:事实上,任何两种字符都是可以转换的,如果兼容,那么就直接转,如果不兼容,那么就查表转。utf-8 保留了ASCII设计规则,即0~127的单字节表示ASCII字符,所有的ASCII字符可以直接添加到utf-8字符流中,而不需要做添加字节的处理。utf-8中的大部分中文字符是用3字节来表示的,所以utf-8应该不能直接和GBK互转。

【7】 utf-8使用的是unicode 字符集,即宽字节。确实,严格来讲,utf-8是针对unicode传输性能差的情况做的优化,它对ASCII定义的字符,采用单字节来传输。

【8】 非专业人员,别研究太深,没啥意思。

【9】最关键:常用的http传输数据,包括form表单提交的数据,都是经过iso-8859-1编码(能否修改有待研究)的,我们在收到后,应该先提取iso-8859-1字节流,然后转成我们要的格式。比如java中:使用:

String str=request.getParameter("属性名");
str=new String(str.getBytes("iso-8859-1"),"utf-8");

如果要在servlet中输出网页,记得把网页的contentType("text/html;charset=utf-8") 如果不设置,是没法显示中文的。