“錕斤拷”的前世今生


不管是在工作中還是生活中,相信很多同學都被“錕斤拷”深深的毒害過,比如這樣,

這樣,

還有這樣,

那么究竟是為什么會出現這些奇怪的字符?接下來我們一探究竟!

ASCII編碼

在計算機底層都是用01進行存儲的,ASCII編碼將所有的字母及符號進行編碼后轉成二進制的01進行存儲,字母和符號占1個字節(即8bit),標准的ASCII碼規定最高位必須為0,因此ASCII編碼只能有128個,轉成十進制即為0-127。標准的ASCII碼表如下:

ASCII碼表只有128個字符,對於英語來說已經夠用了,但是世界上還有很多國家的文字各不相同,這時候就需要一個更加全面的編碼出現。

Unicode(又稱統一碼、萬國碼、單一碼)是計算機科學領域里的一項業界標准。它為每種語言中的每個字符設定了統一並且唯一的二進制編碼。在表示一個Unicode的字符時,通常會用“U+”然后緊接着一組十六進制的數字來表示這個字符。

UTF-8與GBK

UTF-8是針對Unicode的一種可變長度字符編碼。它可以用來表示Unicode標准中的任何字符,而且其編碼中的第一個字節仍與ASCII相容。UTF-8使用一至四個字節為每個字符進行編碼。常用的漢字采用3個字節進行編碼。

因為UTF-8是針對Unicode的一種可變長度的字符編碼,所以它包含了世界上所有字符的編碼,對於那些早錄入的字符,就會優先使用1、2個字節來存儲,對於遲錄入的字符存儲占用的字節就會大一些,這樣,那些遲錄入的字符存儲空間就會很大。

對於一個中文網站,實際上並不需要其他國家的文字出現,但是中國漢字用UTF-8進行編碼,大多數卻占用了3個字節甚至更多字節,這樣就造成了不必要的存儲浪費。為了解決這種問題,中華人民共和國全國信息技術標准化技術委員會制定了一套GB系列的編碼,最常用的就是GBK了。

GBK編碼英文使用單字節編碼,完全兼容ASCII字符,漢字使用了兩個字節進行編碼,其編碼范圍從0x8140(表示16進制)至0xFEFE(剔除xx7F),共23940個碼位,共收錄了21003個漢字,圖形符號 883 個。

為什么要剔除xx7F,因為它對應的ASCII碼表是DEL,意味着要向后刪除一個字符。

為什么會出現“錕斤拷”

Unicode編碼一直持續在收錄各種字符,這就可能會出現各種操作系統支持的Unicode字符不一樣。這也就會導致A上的一個用Unicode編碼的字符,在B上就會出現無法顯示的情況。為了避免這種情況,在Unicode中定義了一個特殊字符�,它的Unicode編碼為0xFFFD。

假如A支持特殊字符,但是B並不支持這個,那么在B中將會用�來代替。

這個字符用UTF-8編碼后,十六進制表示為0xEF 0XBF 0XBD。如果連續出現兩個符號,那么用UTF-8編碼后的十六進制則表示為0xEF 0XBF 0XBD 0xEF 0XBF 0XBD,這時候再轉碼成GBK,因為GBK中用兩個字節表示一個字符,那么上述的字符就成了(0xEFBF),(0xBDEF),(0xBFBD)。出現錕斤拷的原因就是UTF-8轉碼GBK的過程中出現了問題。當然如果想要出現錕斤拷,則至少需要兩個字符出現亂碼。

接下來,我們直接用代碼來看一下效果:

@Test
void contextLoads() throws Exception {
    String str = "�";
    String strCode = new String(str.getBytes("UTF-8"), "GBK");
    System.out.println(strCode);
}

運行結果為錕�,前面也說了如果想要出現錕斤拷,則至少需要為兩個字符,現在再修改一下代碼

@Test
void contextLoads() throws Exception {
    String str = "��";
    String strCode = new String(str.getBytes("UTF-8"), "GBK");
    System.out.println(strCode);
}

運行結果如下為錕斤拷

如果以后再遇到錕斤拷,不要慌,它一定是UTF-8在轉換GBK編碼的時候出現了問題。現在看來GBK編碼雖然減少了內存的浪費,但是也帶來了不少問題。

參考:zhihu.com/question/23024782

點關注、不迷路

如果覺得文章不錯,歡迎關注點贊收藏,你們的支持是我創作的動力,感謝大家。

如果文章寫的有問題,請不要吝嗇,歡迎留言指出,我會及時核查修改。

如果你還想更加深入的了解我,可以微信搜索「Java旅途」進行關注。回復「1024」即可獲得學習視頻及精美電子書。每天7:30准時推送技術文章,讓你的上班路不在孤獨,而且每月還有送書活動,助你提升硬實力!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM