"錕斤拷"的前世此生

不論是在工做中仍是生活中,相信不少同窗都被「錕斤拷」深深的毒害過,好比這樣,web

這樣sql

還有這樣,數據庫

那麼到底是爲何會出現這些奇怪的字符?接下來咱們一探究竟!緩存

ASCII編碼

在計算機底層都是用01進行存儲的,ASCII編碼將全部的字母及符號進行編碼後轉成二進制的01進行存儲,字母和符號佔1個字節(即8bit),標準的ASCII碼規定最高位必須爲0,所以ASCII編碼只能有128個,轉成十進制即爲0-127。標準的ASCII碼錶以下:微信

ASCII碼錶只有128個字符,對於英語來講已經夠用了,可是世界上還有不少國家的文字各不相同,這時候就須要一個更加全面的編碼出現。app

Unicode(又稱統一碼、萬國碼、單一碼)是計算機科學領域裏的一項業界標準。它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼。在表示一個Unicode的字符時,一般會用「U+」而後緊接着一組十六進制的數字來表示這個字符。編輯器

UTF-8與GBK

UTF-8是針對Unicode的一種可變長度字符編碼。它能夠用來表示Unicode標準中的任何字符,並且其編碼中的第一個字節仍與ASCII相容。UTF-8使用一至四個字節爲每一個字符進行編碼。經常使用的漢字採用3個字節進行編碼。flex

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

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

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


< END >

往期精選
  如何保證緩存與數據庫的雙寫一致性?
  Spring 爲啥默認把bean設計成單例的
  Coder,我懷疑你並不會枚舉
  聊聊Mysql中的int(1)
  如何有效防止SQL注入攻擊

本文分享自微信公衆號 - Java旅途(Javatrip)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索