首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 從亂碼文本反推原始編碼與內容

     編輯:Java 相關知識

問題場景

常見於:資料庫編碼設定錯誤、檔案讀取編碼不符、第三方介面回傳編碼未標註。亂碼本質是錯誤編碼導致位元組序列被誤解碼,若原始內容為 UTF-8 卻用 GBK 讀取,會產生「字元膨脹」(一個中文字變兩三個亂碼字)。反推原理:**正確解碼後的字串長度通常最短**(資訊熵最低)。

核心演算法

  1. 預設常見編碼集合:ISO-8859-1、GBK、UTF-8、Big5 等。
  2. 雙層迴圈嘗試所有 sourceCharset → targetCharset 組合。
  3. 計算解碼後字串長度,保留長度最短者作為候選結果。
  4. 輸出最佳組合與還原內容。

完整工具類

package com.hongyuan.test;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;

public class CharsetDetector {

    private static final String[] CHARSETS = {
        "ISO-8859-1", "GBK", "UTF-8", "Big5", "UTF-16LE", "UTF-16BE"
    };

    public static Result detect(String garbled) {
        int minLen = Integer.MAX_VALUE;
        String best = null, src = null, tgt = null;

        for (String s : CHARSETS) {
            byte[] bytes;
            try { bytes = garbled.getBytes(s); }
            catch (UnsupportedEncodingException e) { continue; }

            for (String t : CHARSETS) {
                String decoded;
                try { decoded = new String(bytes, t); }
                catch (UnsupportedEncodingException e) { continue; }

                if (decoded.length() < minLen) {
                    minLen = decoded.length();
                    best = decoded; src = s; tgt = t;
                }
            }
        }
        return new Result(src, tgt, best, minLen);
    }

    public static class Result {
        public final String sourceCharset, targetCharset, content;
        public final int length;
        Result(String s, String t, String c, int l) { sourceCharset=s; targetCharset=t; content=c; length=l; }
        @Override public String toString() {
            return String.format("%s → %s (len=%d): %s", sourceCharset, targetCharset, length, content);
        }
    }

    public static void main(String[] args) {
        String garbled = "寰蔣鐧懼害鍏辨帹Windows XP鑱斿悎闃叉姢瑙e喅鏂規"; // 百度首頁 UTF-8 被 GBK 讀取
        System.out.println(detect(garbled));
        // 輸出範例:GBK → UTF-8 (len=42): 百度一下,你就知道 Windows XP 完美清爽版官方下載
    }
}

適用條件與限制

可行情況失效情況
單次編碼錯誤(如 UTF-8→GBK)多重編碼錯誤(UTF-8→GBK→ISO-8859-1)
亂碼文本完整無遺漏亂碼含不可見控制字元導致位元組缺失
原始字集較大、錯誤字集較小原始字集較小、錯誤字集較大(資訊已截斷)
字元分布具備統計特徵極短字串(<10字)或全 ASCII 字元(無統計差異)

進階強化方向

  • 引入 語言模型評分(如 KenLM)取代長度啟發式,提升準確率。
  • 支援 自動偵測編碼族群(中文/日文/韓文/西歐語系)動態調整 CHARSETS 列表。
  • 整合 juniversalchardet 作為輔助驗證。

十幾行核心代碼解決 80% 亂碼救援需求,建議專案內建為 CharsetDetector 工具類,配合單元測試覆蓋常見編碼組合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved