字符編碼詳解

一些基礎概念

1、1個字節有8位,7位就可以表示0-255共256種狀態,還有1位可當作符號位/特殊標識位。

2、計算機只能識別二進制,但對於人類來說,一長串的二進制交流起來很費勁,所以通過轉換成十六進制來交流。

3、轉換:0010 0001,前4位值等於2,後4位值等於1,十六進制就等於21。爲了防止誤解爲十進制數二十一,所以十六進制一般用0x前綴來表示,即0x21。

4、字符集:統一規定二進制值和字符的對應關係,就叫字符集。常見的有ASCII、GBK、Unicode。

5、字符編碼:字符集規定了某個值對應某個字符,但是並沒有規定這個值要用多少位來顯示、每一位代表什麼含義等等,字符編碼就是規定具體的編碼、解碼規則。常見的有ASCII、GBK、UTF-8/UTF-16。

ASCII

既是字符集,同時又是字符編碼。

作爲字符集,規定0-31對應特定動作(比如換行、輸出等),32-127對應字母、數字、符號等,後來又擴展了128-255對應歐洲字符。

作爲字符編碼,規定每個字符由1個字節的8位表示,最高位是校驗位,剩餘7位的值代表字符。

GBK

計算機傳到中國後,有7000多個漢字需要顯示,於是就誕生了GBK。同樣,既是字符集,有是字符編碼。

作爲字符集,規定0-127與ASCII一樣,127以上的值,分別對應中文、全角標點、羅馬字符、日文片假名等等。

作爲字符編碼,ASCII的字符用1個字節表示,中文用2個字節表示。如果要表示英文,就用1個字節,跟ASCII一樣;如果要表示中文,就用兩個字節,前一個字節範圍0xA1~0xF7,後一個字節範圍0xA1~0xFE。所以,當計算機讀到一個字節的值小於127(0X7F)時,就知道這是一個單字節字符,讀到一個字節的值大於0xA1時,就認爲這是一箇中文字符的第一個字節。

Unicode

美國有ASCII字符集、中國有GBK字符集、日本臺灣等其它國家地區也用自己的字符集,各個字符集之間不能兼容,導致各種不方便,於是誕生了全球統一的字符集Unicode。Unicode收錄了全球的字符,任何字符在Unicode字符集中都能找到對應的值。

UTF-32、UTF-16編碼

UTF32編碼規定每個字符用4個字節共32位來表示,這樣很方便,但有個缺點是浪費空間。

UTF-16規定0~65535之間的字符用2個字節表示,包含了絕大多數字符;65535以上的字符需要一些特殊規則處理,通過4個字節來表示,具體規則可以百度。

UTF-8

000000-00007F之間的字符,用0xxxxxxx表示。0是標識位,xxxxxxx部分表示數值;

000080-0007FF之間的字符,用110xxxxx10xxxxxx表示。110、10是標識位,x部分表示數值,解碼時,把x部分按順序連起來,當成二進制值就行了;

000800-00FFFF之間的字符,用1110xxxx 10xxxxxx 10xxxxxx表示;

010000-10FFFF之間的字符,用11110xxx10xxxxxx10xxxxxx10xxxxxx表示。

Emoji

emoji的字符集有很多版本,所以不統一,下面有個過濾emoji的方法。

過濾emoji,通過for循環,判斷String裏的每一位char是否在emoji區間:

private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }
發佈了35 篇原創文章 · 獲贊 52 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章