Maison > Problème commun > Quelle est la cause des caractères chinois tronqués ?

Quelle est la cause des caractères chinois tronqués ?

青灯夜游
Libérer: 2022-11-09 11:14:04
original
38161 Les gens l'ont consulté

La raison des caractères chinois tronqués : la méthode de décodage et la méthode d'encodage sont incohérentes. Un caractère chinois codé en UTF-8 sera converti en 3 octets, et s'il est codé en gbk, il sera converti en 2 octets ; et un caractère anglais codé en UTF-8 sera converti en 1 octet, s'il est codé en gbk, il le sera. être converti en 1 octet.

Quelle est la cause des caractères chinois tronqués ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, ordinateur Dell G3.

Parlons d'abord de ce que sont les caractères tronqués

Je ne sais pas si quelqu'un y a déjà pensé de cette façon. Une chaîne contient non seulement des caractères, mais également des informations d'encodage qui la cachent. Par exemple, String str = "Bonjour" en Java ; je pensais cela auparavant, la chaîne str cache sa méthode d'encodage unicode ou gbk, iso-8859-1, etc. Cette compréhension est erronée. Les caractères ne sont que des caractères sans aucune autre information. La bonne compréhension devrait être que la chaîne que les gens voient dans un fichier est le système qui lit les informations numériques dans la mémoire et les décode ensuite. Les caractères sont affichés en dernier. , c'est-à-dire que lorsque vous double-cliquez pour ouvrir un fichier texte, le système lira et affichera les informations numériques dans la mémoire. Lorsque vous enregistrez un fichier texte, le système encodera le fichier selon la méthode d'encodage que vous avez définie, puis le mettra. dans la mémoire. Donc les caractères tronqués sont aussi des caractères, juste des caractères étranges, et il n'y a pas de "code".

Parlons ensuite des raisons des codes tronqués

Nous voyons souvent l'explication des raisons des codes tronqués sur Internet : Les codes tronqués sont causés par l'incohérence entre la méthode de décodage et la méthode d'encodage. pas faux, mais la même phrase elle-même est Le code tronqué n'est qu'un résumé, cela ne vous aide pas à comprendre le code tronqué.

La question que nous voulons poser est donc la suivante : pourquoi des codes tronqués apparaissent-ils lorsque la méthode de décodage et la méthode d'encodage sont incohérentes.

Voici les trois méthodes d'encodage utf-8, gbk et iso-8859-1 à titre d'exemples.

     @Test
     public void testEncode() throws Exception {
        String str = "你好",en = "h?h";
        
        System.out.println("========中文字符utf-8=======");
        byte[] utf8 = str.getBytes(); // 以utf-8方式编码 ,default:utf-8
        for (byte b : utf8) {            
            System.out.print(b + "\t");
        }
        
        System.out.println("\n"+"========英文字符utf-8=======");
        byte[] utf8_en = en.getBytes(); // 以utf-8方式编码 ,default:utf-8
        for (byte b : utf8_en) {            
            System.out.print(b + "\t");
        }
        
        System.out.println("\n"+"========中文字符gbk=========");
        byte[] gbk = str.getBytes("gbk");
        for (byte b : gbk) {            
            System.out.print(b + "\t");
        }
        
        System.out.println("\n"+"========英文字符gbk=========");
        byte[] gbk_en = en.getBytes("gbk");
        for (byte b : gbk_en) {            
            System.out.print(b + "\t");
        }
        
        String s = new String(utf8,"utf-8");
        String s1 = new String(utf8,"gbk");
        System.out.println("\n"+s + "====gbk:" + s1);
     }
Copier après la connexion

Testez la méthode ci-dessus, et le résultat imprimé est :

========中文字符utf-8=======
-28 -67  -96 -27  -91 -67  
========英文字符utf-8=======
104 63  104 
========中文字符gbk=========
-60 -29  -70 -61  
========英文字符gbk=========
104 63  104 
你好====gbk:浣犲ソ
------------------------------------------------------------------------------------
Copier après la connexion

On peut conclure que :

Un caractère chinois sera converti en 3 octets s'il est codé avec utf-8, et s'il est codé avec gbk, il sera converti en 2 octets ;

Un caractère anglais sera converti en 1 octet s'il est codé en utf-8, et s'il est codé en gbk, il sera converti en 1 octet.

Il ressort de la dernière ligne d'impression combinée aux lignes 29 à 31 du code que si le tableau d'octets utf8 est décodé en mode utf-8, il n'y aura pas de caractères tronqués, et ce sera toujours le cas. le "Bonjour" original, et s'il est décodé en mode gbk Lors du décodage, trois caractères tronqués sont apparus. Pourquoi y a-t-il 3 au lieu de 2 ?

Parlons ensuite de l'iso-8859-1. Cet encodage est utilisé dans la série anglaise, ce qui signifie qu'il ne peut pas représenter le chinois (si vous souhaitez l'utiliser, vous devez vous fier à d'autres encodages compatibles avec l'iso-8859. -1 méthode d'encodage). Il ne peut pas être lu. Les caractères seront traités comme des points d'interrogation anglais '?'. Le nombre d'encodage iso-8859-1 des points d'interrogation anglais est : 63 (décimal) (en fait, dans presque toutes les méthodes d'encodage). , tous les caractères anglais utilisent une représentation de code d'octet fixe, à l'exception du codage Unicode).

     @Test
     public void testISO() throws Exception {
         String str = "你好";
         byte[] bs = str.getBytes("iso-8859-1");
         for (byte b : bs) {
            System.out.println(b);
         }
         System.out.println(new String(bs,"iso-8859-1"));
         System.out.println(new String(bs,"utf-8"));
         System.out.println(new String(bs,"gbk"));
         System.out.println(new String(bs,"unicode"));         
     }
Copier après la connexion

Imprimer les résultats

63
63
??
??
??
㼿
Copier après la connexion

Explication 63 =》?, tous les chinois sont considérés ?, donc quand ce code est exécuté : byte[] bs = "Hello".getBytes("iso-8859-1" );Les informations ont été perdu.

Execute String str = new String(bs, "any charset"); str n'est plus égal à "Bonjour", mais deux points d'interrogation ??. Ainsi, dans Tomcat, nous rencontrons souvent des caractères chinois se transformant en une longue chaîne de ??????, ce qui en est l'origine.

En iso-8859-1, utf-8 et gbk, un bytecode représente un caractère anglais

En codage Unicode, un bytecode ne peut représenter aucun caractère, et il est stipulé qu'il doit s'agir de deux bytecodes (parfois 4) peut représenter un personnage.

Cela dit, beaucoup de gens peuvent se demander pourquoi tant de méthodes d'encodage sont utilisées. Tous les caractères peuvent-ils être représentés en les unifiant en utf-8 ?

Le codage ne consiste pas seulement à savoir s'il peut représenter des caractères, mais également à transmettre et à stocker.

1. UTF-8 peut en effet représenter presque tous les caractères connus. Comme mentionné précédemment, seuls 3 octets représentent un caractère chinois en codage UTF-8, ce qui prend évidemment de la place et n'est pas propice à la transmission et au stockage (la transmission et le stockage se font tous deux en binaire)

2. Le caractère économise le plus d'espace, comme iso-8859-1. Mais il n’y a pas seulement des personnages anglais dans le monde, mais aussi des personnages de diverses régions et pays. Le nombre de caractères doit donc être supérieur à 2 à la puissance 8.

Ainsi en combinant les deux points ci-dessus, de nombreuses méthodes d'encodage apparaissent naturellement.

Comprendre les règles des différentes méthodes d'encodage : https://jingyan.baidu.com/article/020278118741e91bcd9ce566.html

Pour plus de connaissances liées à la programmation, veuillez visiter : Enseignement de la programmation ! !

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal