Der Grund für verstümmelte chinesische Zeichen: Die Dekodierungsmethode und die Kodierungsmethode sind inkonsistent. Ein in UTF-8 kodiertes chinesisches Zeichen wird in 3 Bytes konvertiert, und wenn es in GBK kodiert ist, wird es in 2 Bytes konvertiert, und ein in UTF-8 kodiertes englisches Zeichen wird in 1 Byte konvertiert, wenn es in GBK kodiert ist in 1 Byte umgewandelt werden.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, Dell G3-Computer.
Ich weiß nicht, ob jemals jemand so darüber nachgedacht hat. Eine Zeichenfolge enthält nicht nur Zeichen, sondern auch Kodierungsinformationen, die sie verbergen. Zum Beispiel String str = „Hallo“ in Java, das habe ich mir vorher gedacht, der String str verbirgt seine Codierungsmethode Unicode-Codierung oder GBK, ISO-8859-1 usw. Dieses Verständnis ist falsch. Das richtige Verständnis sollte sein, dass die Zeichenfolge, die die Leute in einer Datei sehen, das System ist, das die digitalen Informationen im Speicher liest und sie dann in einige Zeichen dekodiert Das heißt, wenn Sie zum Öffnen einer Textdatei doppelklicken, liest das System die digitalen Informationen im Speicher und zeigt sie an. Wenn Sie eine Textdatei speichern, kodiert das System die Datei mit der von Ihnen festgelegten Kodierungsmethode es in die Mitte. Verstümmelte Zeichen sind also auch einige Zeichen, nur seltsame Zeichen, und es gibt keinen „Code“.
Dann lasst uns über die Gründe für verstümmelte Codes sprechenDie Frage, die wir stellen möchten, lautet also: Warum erscheinen verstümmelte Codes, wenn die Decodierungsmethode und die Codierungsmethode inkonsistent sind?
Hier sind die drei Kodierungsmethoden utf-8, gbk und iso-8859-1 als Beispiele.
@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); }
Testen Sie die obige Methode und das gedruckte Ergebnis ist:
========中文字符utf-8======= -28 -67 -96 -27 -91 -67 ========英文字符utf-8======= 104 63 104 ========中文字符gbk========= -60 -29 -70 -61 ========英文字符gbk========= 104 63 104 你好====gbk:浣犲ソ ------------------------------------------------------------------------------------
Man kann daraus schließen, dass:
Ein chinesisches Zeichen wird in 3 Bytes umgewandelt, wenn es mit utf-8 codiert wird, und es wird in 2 Bytes umgewandelt Bytes, wenn es mit GBK codiert ist;
Ein englisches Zeichen wird in 1 Byte konvertiert, wenn es in UTF-8 codiert ist, und wenn es in GBK codiert ist, wird es in 1 Byte konvertiert.
Aus der letzten Druckzeile in Kombination mit den Zeilen 29–31 des Codes ist ersichtlich, dass bei der Decodierung des Byte-Arrays utf8 im UTF-8-Modus keine verstümmelten Zeichen und das ursprüngliche „Hallo“ vorhanden sind " wird immer noch da sein, aber wenn es im GBK-Modus dekodiert wird. Beim Dekodieren erschienen drei verstümmelte Zeichen. Warum gibt es 3 Zeichen statt 2? 6/2=3.
Als nächstes sprechen wir über ISO-8859-1. Diese Kodierung wird in der englischen Serie verwendet, was bedeutet, dass sie kein Chinesisch darstellen kann (wenn Sie sie verwenden möchten, müssen Sie sich auf andere Kodierungen verlassen, die mit ISO-8859 kompatibel sind -1-Kodierungsmethode). Zeichen werden nicht als englische Fragezeichen '?' , alle englischen Zeichen verwenden eine feste Bytecode-Darstellung, mit Ausnahme der Unicode-Codierung).
@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")); }
Ergebnisse drucken
63 63 ?? ?? ?? 㼿
Erläuterung 63 =》?, alle Chinesen werden berücksichtigt?, also wenn dieser Code ausgeführt wird: byte[] bs = "Hallo".getBytes("iso-8859-1" );Informationen wurden verloren.
Execute String str = new String(bs, „any charset“); str ist nicht mehr gleich „Hallo“, sondern zwei Fragezeichen??. Daher stoßen wir in Tomcat häufig auf chinesische Schriftzeichen, die sich in eine lange Folge von ?????? verwandeln, was den Ursprung dafür darstellt.
In ISO-8859-1, UTF-8 und GBK stellt ein Bytecode ein englisches Zeichen dar.
Bei der Unicode-Codierung kann ein Bytecode kein Zeichen darstellen und es ist festgelegt, dass es zwei Bytecodes sein müssen (manchmal 4). kann einen Charakter darstellen.
Nachdem ich so viel gesagt habe, fragen sich viele Leute vielleicht, warum so viele Codierungsmethoden verwendet werden. Kann man sie nicht in UTF-8 vereinheitlichen, um alle Zeichen darzustellen?
Bei der Kodierung geht es nicht nur darum, ob beliebige Zeichen dargestellt werden können, sondern auch um die Übertragung und Speicherung.
1. UTF-8 kann tatsächlich fast alle bekannten Zeichen darstellen. Wie bereits erwähnt, stellen nur 3 Bytes ein chinesisches Zeichen in der UTF-8-Codierung dar, was offensichtlich Platz beansprucht und der Übertragung und Speicherung nicht förderlich ist (Übertragung und Speicherung erfolgen beide binär).Verstehen Sie die Regeln verschiedener Kodierungsmethoden: https://jingyan.baidu.com/article/020278118741e91bcd9ce566.html2 Zweifellos zeigt ein Byte an, dass a Das Zeichen spart am meisten Platz, z. B. iso-8859-1. Aber es gibt nicht nur englische Charaktere auf der Welt, sondern auch Charaktere aus verschiedenen Regionen und Ländern. Die Anzahl der Zeichen muss also größer als 2 hoch 8 sein.
Wenn man also die beiden oben genannten Punkte kombiniert, ergeben sich natürlich viele Codierungsmethoden.
Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Programmierlehre! !
Das obige ist der detaillierte Inhalt vonWas ist die Ursache für verstümmelte chinesische Schriftzeichen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!