Sebab aksara Cina bercelaru: Kaedah penyahkodan dan kaedah pengekodan tidak konsisten. Aksara Cina yang dikodkan dalam UTF-8 akan ditukar kepada 3 bait, dan jika dikodkan dalam gbk ia akan ditukar kepada 2 bait dan aksara Inggeris yang dikodkan dalam UTF-8 akan ditukar kepada 1 bait, jika dikodkan dalam gbk ia akan; ditukar kepada 1 bait.
Persekitaran pengendalian tutorial ini: sistem Windows 7, komputer Dell G3.
Saya tidak tahu sama ada sesiapa pernah berfikir ini Rentetan bukan sahaja mengandungi aksara, tetapi juga mengekod maklumat yang menyembunyikannya. Sebagai contoh, String str = "Hello" dalam Java saya fikir ini sebelum ini, string str menyembunyikan pengekodan unicode kaedah pengekodannya atau gbk, iso-8859-1, dsb. Pemahaman ini adalah salah. Aksara hanyalah aksara tanpa sebarang maklumat lain Pemahaman yang betul adalah bahawa rentetan yang dilihat oleh orang dalam fail ialah maklumat digital dalam memori yang dibaca oleh sistem dan akhirnya memaparkannya . Iaitu, apabila anda klik dua kali untuk membuka fail teks, sistem akan membaca dan memaparkan maklumat digital dalam memori Apabila anda menyimpan fail teks, sistem akan mengekod fail dalam kaedah pengekodan yang anda tetapkan ia menjadi ingatan. Jadi aksara yang bercelaru juga adalah beberapa aksara, cuma aksara yang pelik dan tiada "kod".
Kemudian mari kita bincangkan tentang sebab kod bercelaruJadi soalan yang ingin kami kemukakan ialah: Mengapa kaedah penyahkodan dan kaedah pengekodan berbeza dan aksara bercelaru muncul.
Berikut ialah tiga kaedah pengekodan utf-8, gbk dan iso-8859-1 sebagai contoh.
Menguji kaedah di atas, hasil cetakan ialah:@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); }Boleh disimpulkan bahawa:
========中文字符utf-8======= -28 -67 -96 -27 -91 -67 ========英文字符utf-8======= 104 63 104 ========中文字符gbk========= -60 -29 -70 -61 ========英文字符gbk========= 104 63 104 你好====gbk:浣犲ソ ------------------------------------------------------------------------------------
a Aksara Cina Jika dikodkan dengan utf-8, ia akan ditukar kepada 3 bait Jika dikodkan dengan gbk, ia akan ditukar kepada 1 bait.
Daripada baris terakhir pencetakan digabungkan dengan 29-31 baris kod, kita dapat melihat bahawa jika tatasusunan bait utf8 dinyahkodkan dalam utf-8, akan ada tiada aksara bercelaru, dan ia akan tetap menjadi "Hello", dan jika ia dinyahkod dalam mod gbk, tiga aksara bercelaru muncul Mengapakah terdapat 3 aksara dan bukannya 2?Seterusnya, mari kita bincangkan tentang iso-8859-1 Pengekodan ini digunakan pada siri Inggeris, yang bermaksud ia tidak boleh mewakili bahasa Cina (jika anda ingin menggunakannya, anda mesti bergantung pada pengekodan lain yang serasi. dengan kaedah pengekodan iso-8859-1). kaedah, semua aksara Inggeris ditetapkan dengan 1 perwakilan bytecode, kecuali pengekodan unicode). Cetak hasil
Penjelasan 63 =》?, semua bahasa Cina dianggap?, jadi apabila kod ini dilaksanakan: byte[] bs = "You OK".getBytes ("iso-8859-1");Maklumat telah hilang.
Lakukan String str = new String(bs, "mana-mana set aksara"); str tidak lagi bersamaan dengan "Hello", tetapi dua tanda tanya??. Jadi dalam kucing jantan kita sering menemui aksara Cina yang berubah menjadi rentetan panjang ??????, yang merupakan asal usul ini.
@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")); }Dalam iso-8859-1, utf-8 dan gbk, satu bytecode mewakili aksara Inggeris Dalam pengekodan unicode, satu bytecode tidak boleh mewakili sebarang aksara, dan ia ditetapkan. dua kod bait (kadang-kadang 4) untuk mewakili aksara.
63 63 ?? ?? ?? 㼿
Setelah berkata begitu banyak, ramai orang mungkin bertanya mengapa begitu banyak kaedah pengekodan digunakan. Bukankah mustahil untuk menyatukannya ke dalam utf-8 untuk mewakili semua aksara?
Pengekodan bukan sahaja mengenai sama ada ia boleh mewakili sebarang aksara, tetapi juga mengenai penghantaran dan storan.
1. UTF-8 sememangnya boleh mewakili hampir semua aksara yang diketahui. Seperti yang dinyatakan sebelum ini, hanya 3 bait mewakili aksara Cina dalam pengekodan UTF-8, yang jelas mengambil ruang dan tidak kondusif untuk penghantaran dan penyimpanan (penghantaran dan penyimpanan dilakukan dalam binari) 2 bait mewakili satu aksara dalam cara yang paling menjimatkan ruang, seperti iso-8859-1. Tetapi terdapat bukan sahaja aksara Inggeris di dunia, tetapi juga watak dari pelbagai wilayah dan negara. Jadi bilangan aksara mestilah lebih besar daripada 2 hingga kuasa ke-8.Jadi dengan menggabungkan dua perkara di atas, banyak kaedah pengekodan akan muncul secara semula jadi.
Ketahui peraturan pelbagai kaedah pengekodan: https://jingyan.baidu.com/article/020278118741e91bcd9ce566.html
Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati: Pengajaran Pengaturcaraan! !
Atas ialah kandungan terperinci Apakah punca watak Cina bercelaru?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!