亂碼 上節說到亂碼出現的主要原因,即在進行編碼轉換的時候,如果將原來的編碼識別錯了,併進行了轉換,就會發生亂碼,而且這時候無論怎麼切換查看編碼的方式,都是不行的。 我們來看一個這種錯誤轉換後的亂碼,還是用上節的例子,二進位是(16進位表示):C3 80 C3 8F C3 82 C3 AD,無論按哪種 ...
亂碼
上節說到亂碼出現的主要原因,即在進行編碼轉換的時候,如果將原來的編碼識別錯了,併進行了轉換,就會發生亂碼,而且這時候無論怎麼切換查看編碼的方式,都是不行的。
我們來看一個這種錯誤轉換後的亂碼,還是用上節的例子,二進位是(16進位表示):C3 80 C3 8F C3 82 C3 AD,無論按哪種編碼解析看上去都是亂碼:
UTF-8 | ÀÏÂí |
Windows-1252 | ÀÃÂà |
GB18030 | 脌脧脗鉚 |
Big5 | ���穩 |
雖然有這麼多形式,但我們看到的亂碼形式很可能是"ÀÏÂí",因為在例子中UTF-8是編碼轉換的目標編碼格式,既然轉換為了UTF-8,一般也是要按UTF-8查看。
亂碼恢復
"亂"主要是因為發生了一次錯誤的編碼轉換,恢復是要恢復兩個關鍵信息,一個是原來的二進位編碼方式A,另一個是錯誤解讀的編碼方式B。
恢復的基本思路是嘗試進行逆向操作,假定按一種編碼轉換方式B獲取亂碼的二進位格式,然後再假定一種編碼解讀方式A解讀這個二進位,查看其看上去的形式,這個要嘗試多種編碼,如果能找到看著正常的字元形式,那應該就可以恢復。
我們舉個例子來說明,假定亂碼形式是"ÀÏÂí",嘗試多種B和A來看字元形式,如下圖所示:
可以看出,第一行是正確的,也就是說原來的編碼其實是A即GB18030,但被錯誤解讀成了B即Windows-1252了。
恢復的討論
可以看出,這種嘗試需要進行很多次,上面例子嘗試了常見編碼GB18030/Windows 1252/Big5/UTF-8共十二種組合。這四種編碼是常見編碼,在大部分實際應用中應該夠了,但如果你的情況有其他編碼,可以增加一些嘗試。
不是所有的亂碼形式都是可以恢復的,如果形式中有很多不能識別的字元如�?,則很難恢復,另外,如果亂碼是由於進行了多次解析和轉換錯誤造成的,也很難恢復。
上面的嘗試可以手工進行,藉助文件編輯器如EditPlus, NotePad++, UltraEdit進行編碼轉換和切換查看編碼的方式。
但我們是學編程的,這種嘗試當然應該可以通過寫程式自動進行,程式甚至應該可以自動判定哪些嘗試是無效的,哪些嘗試是可能有效的。
那怎麼寫程式呢?這個問題,由於牽涉的內容較多,此時我們暫不介紹,留待後續文章說明。
小結
上節和本節介紹了編碼的知識,亂碼的原因及恢復方法,這些都是與語言無關的。
接下來,是時候看看在Java中如何表示和處理字元了,我們知道Java中用char類型表示一個字元,但在第三節我們提到了一個問題,即"字元類型怎麼也可以進行算術運算和比較?"。
我們需要對Java中的字元類型有一個更為清晰和深刻的理解。
----------------
未完待續,查看最新文章,敬請關註微信公眾號“老馬說編程”(掃描下方二維碼),深入淺出,老馬和你一起探索Java編程及電腦技術的本質。原創文章,保留所有版權。