乱码
上节说到乱码出现的主要原因,即在进行编码转换的时候,如果将原来的编码识别错了,并进行了转换,就会发生乱码,而且这时候无论怎么切换查看编码的方式,都是不行的。
我们来看一个这种错误转换后的乱码,还是用上节的例子,二进制是(16进制表示):C3 80 C3 8F C3 82 C3 AD,无论按哪种编码解析看上去都是乱码:
UTF-8 | ÀÏÂí |
Windows-1252 | ÀÃÂà |
GB18030 | 脌脧脗铆 |
Big5 | ���穩 |
虽然有这么多形式,但我们看到的乱码形式很可能是"ÀÏÂí",因为在例子中UTF-8是编码转换的目标编码格式,既然转换为了UTF-8,一般也是要按UTF-8查看。
乱码恢复
"乱"主要是因为发生了一次错误的编码转换,恢复是要恢复两个关键信息,一个是原来的二进制编码方式A,另一个是错误解读的编码方式B。
恢复的基本思路是尝试进行逆向操作,假定按一种编码转换方式B获取乱码的二进制格式,然后再假定一种编码解读方式A解读这个二进制,查看其看上去的形式,这个要尝试多种编码,如果能找到看着正常的字符形式,那应该就可以恢复。
我们举个例子来说明,假定乱码形式是"ÀÏÂí",尝试多种B和A来看字符形式,如下图所示:
可以看出,第一行是正确的,也就是说原来的编码其实是A即GB18030,但被错误解读成了B即Windows-1252了。
恢复的讨论
可以看出,这种尝试需要进行很多次,上面例子尝试了常见编码GB18030/Windows 1252/Big5/UTF-8共十二种组合。这四种编码是常见编码,在大部分实际应用中应该够了,但如果你的情况有其他编码,可以增加一些尝试。
不是所有的乱码形式都是可以恢复的,如果形式中有很多不能识别的字符如�?,则很难恢复,另外,如果乱码是由于进行了多次解析和转换错误造成的,也很难恢复。
上面的尝试可以手工进行,借助文件编辑器如EditPlus, NotePad++, UltraEdit进行编码转换和切换查看编码的方式。
但我们是学编程的,这种尝试当然应该可以通过写程序自动进行,程序甚至应该可以自动判定哪些尝试是无效的,哪些尝试是可能有效的。
那怎么写程序呢?这个问题,由于牵涉的内容较多,此时我们暂不介绍,留待后续文章说明。
小结
上节和本节介绍了编码的知识,乱码的原因及恢复方法,这些都是与语言无关的。
接下来,是时候看看在Java中如何表示和处理字符了,我们知道Java中用char类型表示一个字符,但在第三节我们提到了一个问题,即"字符类型怎么也可以进行算术运算和比较?"。
我们需要对Java中的字符类型有一个更为清晰和深刻的理解。
----------------
未完待续,查看最新文章,敬请关注微信公众号“老马说编程”(扫描下方二维码),深入浅出,老马和你一起探索Java编程及计算机技术的本质。原创文章,保留所有版权。