Maison >Java >javaDidacticiel >Quel est le processus de conversion de l'encodage Java ?

Quel est le processus de conversion de l'encodage Java ?

PHPz
PHPzavant
2023-04-19 13:10:061763parcourir

    Conversion d'encodage en java (en prenant utf8 et gbk comme exemple)

    Dans le développement javaweb normal, nous constatons souvent le besoin de conversion de caractères. Il y aura le phénomène de conversion de caractères chinois tronqués. Comment le résoudre et. le principe de conversion. Jusqu'à présent, j'étais confus, alors j'ai écrit un code de test pour l'essayer. J'ai finalement clarifié l'encodage et suis arrivé à la conclusion en premier :

    utf8 stocke actuellement différents encodages de langues. , utf8 est utilisé pour l'encodage et le décodage dans le développement grand public. La méthode ne produira pas de codes tronqués. Les situations suivantes entraîneront des codes tronqués : 1, gbk (chinois), iso-8859-1 (pas de chinois) et d'autres méthodes d'encodage. ne peut utiliser que la méthode correspondante pour décoder, sinon des caractères tronqués

    • 2 L'utilisation de utf8 pour l'encodage et le décodage en utilisant d'autres méthodes entraînera des caractères tronqués et une conversion est requise

    • 3. iso-8859-1) sans caractères correspondants (chinois), ce qui entraînera des codes tronqués et l'impossibilité de restaurer le décodage

    • Ce qui suit est un test de code pour la situation ci-dessus

    • 1 Comment encoder, c'est comment décoder
    /**
     * 测试编码转换 中文 => 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"));//测试
    }
    .

    Encodage utf8-décodage de forme incorrecte

    /**
     * 测试编码转换 中文 => 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"));//娴嬭瘯
    }

    La bonne façon est d'appuyer sur la mauvaise forme de décodage (gbk) comme transit, de la réencoder (utf8-encode) selon la mauvaise forme (gbk), puis d'utiliser utf8 pour effectuez un décodage correct (utf8-decode) pour obtenir les caractères originaux

    /**
     * 测试编码转换 中文 => 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. Aucun encodage de caractères correspondant

    @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));//??
        }

    Dans ce cas, même si la méthode d'encodage d'origine est utilisée pour le décodage, les caractères ne peuvent pas être restaurés, et c'est le cas. un état irréversible.

    Conversion du format d'encodage Java et récupération du code tronqué

    Comment effectuer la conversion du format d'encodage en Java

    La signification de la ligne de code suivante est la suivante : Obtenez le code binaire de la chaîne cible str au format d'encodage gbk. , puis réencodez le code binaire en chaîne selon le format d'encodage utf8. Bien sûr, la méthode d'écriture suivante sera tronquée à 100 % car le format d'encodage est incohérent

    new String(str.getBytes("gbk"),"utf8")

    Tout d'abord, dans quelles circonstances le code sera-t-il utilisé. être tronqué ? Si vous souhaitez transmettre une chaîne, vous devez d'abord convertir la chaîne en un flux d'octets selon un certain format de codage. Lorsque le flux d'octets est transmis au récepteur, puis convertir le flux d'octets selon un certain format de codage. dans une chaîne. Les caractères tronqués sont également générés lors du processus de reconversion en chaîne. Voici mon test des caractères chinois tronqués :

      String str="彩虹";
            String [] a=new String[] {"gbk","unicode","utf8","gb2312"};
            for (int i=0;i<a.length;i++){
                for (int j=0;j<a.length;j++){
                    System.out.println("二进制格式:   "+a[i]+"编码格式:  "+a[j]);
                    System.out.println("编码后的字符串:  "+new String(str.getBytes(a[i]),a[j]));
     
                }
            }

    Format binaire : format d'encodage gbk : gbk

    Chaîne codée : Rainbow

    Format binaire. : format d'encodage gbk : unicode

    Chaîne codée : 닊뫧

    Format binaire : format d'encodage gbk : utf8
    Chaîne codée : �ʺ�

    Format binaire : format d'encodage gbk : gb2312
    Chaîne codée : Rainbow
    format binaire : format d'encodage unicode : gbk
    chaîne codée : _i唝
    format binaire : format d'encodage unicode : unicode
    chaîne encodée : arc-en-ciel
    format binaire : format d'encodage unicode : utf8
    chaîne codée : ��_i�y
    Format binaire : format d'encodage unicode : gb2312
    Encodé chaîne : ��_i�y
    Format binaire : format d'encodage utf8 : gbk
    Chaîne codée : 褰╄櫣
    Format binaire : format d'encodage utf8 : unicode
    Chaîne codée : ꧨ馹
    Format binaire : format d'encodage utf8 : utf8
    Encodé chaîne : arc-en-ciel
    Format binaire : format d'encodage utf8 : gb2312
    Chaîne codée :褰╄��
    Format binaire : gb2312 format d'encodage : gbk
    Chaîne codée : arc-en-ciel
    Format binaire : gb2312 format d'encodage : unicode
    Chaîne codée : 닊뫧
    Binaire format : gb2312 format d'encodage : utf8
    Chaîne codée : �ʺ�
    Format binaire : gb2312 format d'encodage : gb2312
    Chaîne codée : Rainbow


    On peut voir que si le format d'encodage binaire et le format d'encodage de la chaîne sont différents , des caractères tronqués apparaîtront.

    Pourquoi il n'y a pas de code tronqué dans la conversion entre gbk et gb2312 La raison pour laquelle il n'y a pas de code tronqué dans la conversion entre gbk et gb2312 est parce que gbk est une version améliorée de gb2312 et prend en charge davantage de chinois. codages de caractères, donc si le format de codage binaire est gbk et le format de décodage est gb2312, cette situation Il est possible que certains caractères chinois soient tronqués. Les données tronquées peuvent-elles être reconverties Les caractères tronqués dans les résultats ci-dessus peuvent être grossièrement divisés en ? deux types, l'un est une combinaison complexe de caractères chinois et de graphiques, et l'autre est "?".

    S'il y a des points d'interrogation dans les données tronquées que vous souhaitez récupérer, alors la possibilité de récupérer ces données est très faible. Parce qu'à l'exception du "?", les autres caractères tronqués ont en fait leurs propres règles de codage, à condition qu'ils soient décodés et suivis à l'envers. Ils peuvent être restaurés en recodant le format de codage correct. Cependant, "?" est recompilé selon un certain format de codage, les octets des données d'octets qui ne peuvent pas être convertis en caractères significatifs selon le format de codage seront convertis en "?", donc même s'ils sont codés de manière inversée dans un flux d'octets, tous ". ?" sera converti dans le même octet, perdant ainsi sa propre signification.

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

           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
    编码后的字符串:  彩虹

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer