關於作者:程式猿石頭(ID: tangleithu),現任阿里巴巴技術專家,清華學渣,前大疆後端 Leader。歡迎關注,交流和指導!
本文首發於微信公眾號,原文連結,轉載請全文保留。
以一首七言絕句作為開篇:
手持兩把錕斤拷
口中疾呼燙燙燙
腳踏千朵屯屯屯
笑看萬物鍩鍩鍩
� 為何物?
在上次石頭哥發的這篇文章中 —— 你可能也會掉進這個簡單的 String 的坑,講述了因字元編碼問題而連續踩坑的經歷,文中有一個神奇的字元 “�”。
其實,這個 “�” 真是無處不在,比如大名鼎鼎的微信:
再比如,封面圖中,單價22元的“錕斤拷錕斤拷”,再隨便百度一把:
要弄清這個問題,還得先從編碼談起。
因為在計算機的眼裡,都是二進位制,具體用哪些二進位制數字表示哪個符號,這就是編碼。不要把編碼想象得太複雜,其實就是一個很簡單的 mapping。
比如大家所熟知的 ASCII 編碼,規定了
二進位制的0100 0001
,也就是十進位制的65
,代表的含義就是大寫字母 A
。
�
也是一種編碼字元,就跟上面的 A
一樣一樣的,它是 UNICODE 編碼方式中的一個特殊的字元,也就是 0xFFFD(65533),語義是一個佔位符(REPLACEMENT CHARACTER),用來表達未知的,自己不認識的東西。
比如上篇文章中的實驗截圖的,紅色部分圈出來的對應的字元,UTF-8 編碼都不認識,所以按照 UNICODE 的定義,我就只好用統一的一個佔位符 —— 0xFFFD(65533)
來表示。
為什麼會出現“錕斤拷”?
我們接著上篇的例子來看, 如下圖所示,仍然從 “程式猿石頭” 對應二進位制編碼擷取部分:
如上圖所示,第 18 行的位元組陣列 new byte[] {-25, -119, -25, -116}
,UTF-8
恰好都不認識,因此只能用佔位符替換。
這種情況,在編碼轉換過程中確實也比較常見,如果雙方沒溝通清楚,確實很容易出現互相不認識的情況。
在中文系統中,常見的字元編碼是 GBK,這個時候,因為大家沒提前商量清楚,我就預設按照 GBK 給你編碼看看。
驚不驚喜意不意外……
其實是因為,�
用 UTF-8
編碼後變成了 0xEFBFBD
(就是上面的位元組陣列 [-17, -65, -67]
),兩個連起來就是 0xEFBFBDEFBFBD
,也就是上面的位元組陣列[-17, -65, -67, -17, -65, -67]
。
而 GBK 編碼依然採用雙位元組編碼方案,因此上面的 6 位元組 0xEFBFBDEFBFBD
,就被拆成了 3 個 2 位元組字元即 0xEFBF, 0xBDEF, 0xBFBD
對應 GBK 編碼裡面就是:錕(0xEFBF),斤(0xBDEF),拷(0xBFBD)
現在,你知道了嗎?
留個作業題:開篇的七言絕句,你知道另外的梗是來自哪裡嗎?歡迎留言討論。
最近看到一份來自阿里巴巴開源的學習資料,涵蓋了大前端、客戶端、服務端、演算法等多個技術領域,全書內容⻚數1600+,現在分享給大家。點選原文獲取。