UTF-8转GBK的悲剧:特殊字符C2A0

问题表现

闪印发布后经常会发现传给印象派的作品描述XML(GBK编码)中一些文字信息经常包含乱码,而且会一乱到底,甚至导致不同页的错乱。刚开始一直都没有什么头绪,后来终于发现了问题所在:GBK的字符集过小,对一些特殊字符的转码会出现乱码。一些生僻字也就算了,但是其中却包括这个字符C2A0————一个在网页上经常使用排版用全角空格。用户从网页端拷贝了一段包含此字符的字符串,复制到界面上显示正常,保存到作品XML文件中(UTF8编码),显示正常。但是上传作品时由于将相应的XML编码格式转换成GBK,于是出现了乱码。

处理方法

方法一:转换时对文本信息做特殊处理,用0×20代替掉0xC2A0。 方法二:作品XML文件直接以UTF8编码传输。

方法一有点头疼治头脚疼治脚的味道,虽然解决了这个问题,但是总归不够规范不够完美—-很多页面都是这么做。而方法二则需要服务器支持,但可以完美的解决这个问题。以前服务器之所以用GBK编码很大的理由可能在于GBK相对UTF8更省空间—-在这么个硬盘空间足够,带宽足够的现状下,节约出来的那么点东西又有什么用呢?

还有一个值得一提的问题是GBK对字符解析失败引起的问题是有多米诺骨牌效应的:UTF8编码的字符第一个字节有且只有六种可能:(如图)

此处输入图片的描述

而GBK则没有这样的便利,在解析第一个字节出错后,并没有任何规则来说明后续的那个字节到底是上一个错误字符的一部分,还是下一个字符的起始字符。默认的处理是将解析出错的字节标注为0x3F(即?),下一个字节作为下一个字符的起始位置来进行解析。这样的规则就很容易引起后续的解析全部出错。