前言

从长沙辞职跑到深圳,找房子找工作适应新的工作环境超级忙。之前一直没时间好好写博客,今天难得有空就上来写点东西吧!

都9102年了,没想到还能有那么多乱码问题。之前的工作基本上前后端统一编码就完事了;话不多说,既然遇到了就干脆搞搞明白吧!

实践出真知

网上很多关于乱码还原的解决办法,都是很片面甚至是误导性的。逆向转码是提到最多的,如下:

假定errStr是原本为gbk编码格式的字符串,但是使用utf-8进行解码从而形成了乱码。错误示范,并不能还原乱码

String str = new String(errStr.getBytes(StandardCharsets.UTF_8), "GBK");

逆向转码乍一看有道理,但真的经得起推敲吗?

实验一

假定乱码场景为:原本为gbk编码的字符串错误的使用了utf-8进行解码形成了乱码。现需要把这个乱码进行还原
按照网上很多人说的乱码还原的解决办法,即逆向转码就能解决。事实真的如此吗?

public static void main(String[] args) throws UnsupportedEncodingException {
        String unicodeStr = "这是一串原本为GBK编码格式的字符串";
        // gbks 为GBK编码格式
        byte[] gbks = unicodeStr.getBytes("GBK");

        // 解码验证 GBK解码方式不乱码而UTF8乱码则说明是GBK
        String errStr = new String(gbks, StandardCharsets.UTF_8);
        System.out.println(errStr);

        String rightStr = new String(gbks, "GBK");
        System.out.println(rightStr);

        // 将原本为GBK编码格式 的乱码字符串 还原
        // 乱码字符串进行还原
        byte[] errBytes = errStr.getBytes(StandardCharsets.UTF_8);
        String str = new String(errStr.getBytes(StandardCharsets.UTF_8), "GBK");
        System.out.println(str);
    }

控制台输出:

很显然一串原本为GBK编码格式的当使用了utf8解码而形成了乱码。当使用逆向转码试图还原乱码时形成了新的乱码。

事实上如果乱码中出现了问号,则表示这部分已经丢失了,是没有办法还原了的。即这串乱码是不可逆的。

实验二

假定乱码场景为:原本为utf8编码的字符串错误的使用了gbk进行解码形成了乱码。现需要把这个乱码进行还原

public static void main(String[] args) throws UnsupportedEncodingException {
        String unicodeStr = "这是一串原本为UTF-8编码格式的字符串";
        // gbks 为GBK编码格式
        byte[] utf8s = unicodeStr.getBytes(StandardCharsets.UTF_8);

        // 解码验证 utf8解码方式不乱码而gbk乱码则说明是utf8
        String rightStr = new String(utf8s, StandardCharsets.UTF_8);
        System.out.println(rightStr);

        String errStr = new String(utf8s, "GBK");
        System.out.println(errStr);

        // 将原本为utf8编码格式 的乱码字符串 还原
        // 乱码字符串进行还原

        byte[] gbks = errStr.getBytes("GBK");
        String str = new String(errStr.getBytes("GBK"), StandardCharsets.UTF_8);
        System.out.println(str);
    }

控制台输出:

当原本为utf8的字符串错误的使用了gbk解码后形成的乱码。经过逆向转码,是可以部分还原的,但是依然不能百分百还原!

最后

有很多一知半解的去解答别人关于乱码还原问题的解决方案时,简直就是误人子弟,乱码问题的关键在于从源头抓起,统一编码,使用正确的解码方式进行解码。

简言之:就是在形成乱码的那一步遏制,而不是乱码已经形成了再去想办法还原!

这篇写的很片面,下一篇我将分析一下编码解码以及乱码形成的具体原因,以及为什么原本为utf8的字符串形成的乱码部分可逆,部分不可逆。我目前也正在找资料,有知道的小伙伴不妨留言。。❀

12-27 19:29
查看更多