Javaエンコーディング変換プロセスとは何ですか?

PHPz
リリース: 2023-04-19 13:10:06
転載
1730 人が閲覧しました

    Java でのエンコード変換 (utf8 と gbk を例にします)

    通常の JavaWeb 開発では、文字変換の必要性がよくあります。文字化けになる問題とその解決方法と変換原理がまだよく分からないので試しにテストコードを書いて、ようやくエンコードを解明しました。

    utf8 に格納 言語エンコードにはさまざまなものがありますが、現在主流の開発では utf8 がエンコード、デコードに使用されています この方法ではコード化けが発生しません 以下のような状況では文字化けが発生しますcode

    • 1、gbk (中国語)、iso-8859-1 (中国語不可) などの他の方法でエンコードした場合は、対応する方法のみを使用してデコードできます。それ以外の場合は、

    • 2 は文字化けします。他の方法でエンコードおよびデコードするには utf8 を使用してください。文字化けが発生するため、変換が必要です。

    • 3対応する文字 (中国語) のない文字セット (iso-8859-1) を使用してエンコードすると、文字化けが発生し、デコードを復元できません

    #以下は、上記の状況に対するコード テストです。

    1. エンコード方法はデコード方法です

    /**
     * 测试编码转换 中文 => utf-8 编码 - 解码
     */
    @Test
    public void test0() {
        String test = "测试";
        System.out.println(Arrays.toString(test.getBytes(StandardCharsets.UTF_8)));//[-26, -75, -117, -24, -81, -107]
        System.out.println(new String(test.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));//测试
    }
    ログイン後にコピー
    /**
     * 测试编码转换 中文 => gbk 编码 - 解码
     */
    @Test
    public void test1() throws UnsupportedEncodingException {
        String test = "测试";
        System.out.println(Arrays.toString(test.getBytes("gbk")));//[-78, -30, -54, -44]
        System.out.println(new String(test.getBytes("gbk"), "GBK"));//测试
    }
    ログイン後にコピー

    utf8 エンコード - 間違った形式のデコード

    /**
     * 测试编码转换 中文 => utf-8 编码- gbk解码
     */
    @Test
    public void test2() throws UnsupportedEncodingException {
        String test = "测试";
        System.out.println(Arrays.toString(test.getBytes(StandardCharsets.UTF_8)));//[-26, -75, -117, -24, -81, -107]
        System.out.println(new String(test.getBytes(StandardCharsets.UTF_8), "gbk"));//娴嬭瘯
    }
    ログイン後にコピー

    正しいアプローチは、間違ったデコード形式 (gbk) をデコードとして使用することです。転送し、間違った形式 (gbk) に従って再エンコード (utf8-encode) し、utf8 を使用して正しいデコード (utf8-decode) を実行して、元の Character

    /**
     * 测试编码转换 中文 => utf-8 编码 - gbk 解码 ===> gbk 编码 - utf-8解码
     * "测试" => (utf8-encode)[-26, -75, -117, -24, -81, -107] => (gbk-decode)娴嬭瘯
     * "娴嬭瘯" => (utf8-encode)[-26, -75, -117, -24, -81, -107] => (utf8-decode)"测试"
     */
    @Test
    public void test3() throws UnsupportedEncodingException {
        String test = "测试";
        String test_gbk_utf8 = new String(test.getBytes(StandardCharsets.UTF_8), "gbk");
        System.out.println(test_gbk_utf8);//娴嬭瘯
        String test_utf8_gbk = new String(test_gbk_utf8.getBytes("gbk"), StandardCharsets.UTF_8);
        System.out.println(test_utf8_gbk);//测试
    
    }
    ログイン後にコピー

    3 を取得します。文字エンコード

    @Test
        public void test4() throws UnsupportedEncodingException {
            String test = "测试";
            System.out.println(Arrays.toString(test.getBytes(StandardCharsets.ISO_8859_1)));//[63, 63]
            System.out.println(new String(test.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.ISO_8859_1));//??
        }
    ログイン後にコピー

    この場合、元のエンコード方式でデコードしても文字を復元することはできず、不可逆的な状態になります

    Javaエンコード 形式変換と文字化け復旧

    java でエンコード形式の変換を実行する方法

    次のコード行の意味は次のとおりです。ターゲット文字列 str の gbk エンコード形式のバイナリ コードを取得し、バイナリを変換します。コードはutf8のエンコード形式に従って文字列に再エンコードされますが、当然ながら以下の書き方はエンコード形式がバラバラなので100%文字化けします。コードが文字化けしますか?

    文字列を送信したい場合は、まず文字列を特定のエンコード形式に従ってバイト ストリームに変換する必要があります。バイト ストリームが受信者に送信されると、バイト ストリームは特定のエンコード形式に従って文字列に変換する必要があります。文字化けは、文字列に再変換する過程でも発生します。以下は中国語の文字化けのテストです:

    new String(str.getBytes("gbk"),"utf8")
    ログイン後にコピー

    バイナリ形式: gbk エンコード形式: gbk

    エンコードされた文字列: Rainbow
    binary 形式: gbk エンコード形式: unicode

    エンコードされた文字列: 닊뫧
    バイナリ形式: gbk エンコード形式: utf8
    エンコードされた文字列: �ʺ�
    バイナリ形式: gbk エンコード形式: gb2312
    エンコードされた文字列: Rainbow
    バイナリ形式: unicode エンコード形式: gbk
    エンコードされた文字列: �_i唝
    バイナリ形式: unicode エンコード形式: unicode
    エンコード後 文字列: Rainbow
    バイナリ形式: Unicode エンコード形式: utf8
    エンコード文字列: ��_i�y
    バイナリ形式: Unicode エンコード形式: gb2312
    エンコード文字列: � �_i�y
    バイナリ形式: utf8 エンコード形式: gbk
    エンコードされた文字列: 褰╄櫣
    バイナリ形式: utf8 エンコード形式: unicode
    エンコードされた文字列: ꧨ馹
    バイナリ形式: utf8 エンコード形式: utf8
    エンコード文字列: Rainbow
    バイナリ形式: utf8 エンコード形式: gb2312
    エンコード文字列: 褰╄��
    バイナリ形式: gb2312 エンコード形式: gbk
    エンコード文字列:レインボー
    バイナリ形式: gb2312 エンコード形式: unicode
    エンコードされた文字列: 닊뫧
    バイナリ形式: gb2312 エンコード形式: utf8
    エンコードされた文字列: �ʺ�
    バイナリ形式: gb2312 エンコード形式: gb2312
    エンコードされた文字列: Rainbow


    バイナリエンコード形式と文字列の異なるエンコード形式が文字化けを引き起こすことがわかります。 gbk と gb2312 間の変換?

    gbk と gb2312 間の変換でコードが文字化けしない理由は、gbk が gb2312 の拡張バージョンであり、より多くの中国語の文字エンコーディングをサポートしているためです。は gbk で、デコード形式は gb2312 であるため、一部の中国語の文字が文字化けする可能性があります。

    文字化けしたデータは元に戻すことができますか?

    上記の結果の文字化けは、おおよそ漢字と図形が複雑に組み合わされたものと、「?」の2種類に分けられます。 「?」以外の文字化けには独自のエンコード規則があるため、逆デコードして正しいエンコード形式で再エンコードすれば回復可能です。ただし、「?」以外は文字化けします。 ", バイトストリームを特定のエンコード形式に従って再コンパイルすると、バイトデータ内のエンコード形式に従って意味のある文字に変換できないバイトは「?」に変換されるため、バイトストリームが逆であってもバイト ストリームにエンコードすると、エンコード形式に従ってバイト データ内のすべてのバイトを意味のある文字に変換できません。「?」は同じバイトに変換され、それ自体の意味が失われます。

    如果乱码中不包含"?",那么还是有希望转换回去的,我以上述乱码中的 "褰╄櫣" 为例重新进行了一次转换,代码如下:

           String str="褰╄櫣";
            String [] charset=new String[] {"gbk","unicode","utf8","gb2312"};
            for (int i=0;i<charset.length;i++){
                for (int j=0;j<charset.length;j++){
                    System.out.println("二进制格式:   "+charset[i]+"编码格式:  "+charset[j]);
                    System.out.println("编码后的字符串:  "+new String(str.getBytes(charset[i]),charset[j]));
     
                }
            }
    ログイン後にコピー

    二进制格式:   gbk编码格式:  gbk
    编码后的字符串:  褰╄櫣
    二进制格式:   gbk编码格式:  unicode
    编码后的字符串:  ꧨ馹
    二进制格式:   gbk编码格式:  utf8
    编码后的字符串:  彩虹
    二进制格式:   gbk编码格式:  gb2312
    编码后的字符串:  褰╄��
    二进制格式:   unicode编码格式:  gbk
    编码后的字符串:  ��0%Dj�
    二进制格式:   unicode编码格式:  unicode
    编码后的字符串:  褰╄櫣
    二进制格式:   unicode编码格式:  utf8
    编码后的字符串:  ���0%Dj�
    二进制格式:   unicode编码格式:  gb2312
    编码后的字符串:  ���0%Dj�
    二进制格式:   utf8编码格式:  gbk
    编码后的字符串:  瑜扳晞娅�
    二进制格式:   utf8编码格式:  unicode
    编码后的字符串:  냢閄�
    二进制格式:   utf8编码格式:  utf8
    编码后的字符串:  褰╄櫣
    二进制格式:   utf8编码格式:  gb2312
    编码后的字符串:  瑜扳��娅�
    二进制格式:   gb2312编码格式:  gbk
    编码后的字符串:  褰╄?
    二进制格式:   gb2312编码格式:  unicode
    编码后的字符串:  ꧨ�
    二进制格式:   gb2312编码格式:  utf8
    编码后的字符串:  彩�?
    二进制格式:   gb2312编码格式:  gb2312
    编码后的字符串:  褰╄?

    可以看到 其中一种转换方式成功的将乱码转变回了正常的中文汉字

    二进制格式:   gbk编码格式:  utf8
    编码后的字符串:  彩虹

    以上がJavaエンコーディング変換プロセスとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    関連ラベル:
    ソース:yisu.com
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    人気のチュートリアル
    詳細>
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート