字符集和字符編碼

亂碼

亂碼是怎么出現(xiàn)的呢?對同一組二進制數(shù)據(jù),不同的編碼會解析出不同的字符,用對了編碼,解析出來的字符組成的文字是有意義的,用錯了編碼,解析出來的字符組成的文字是沒意義的,也就是通常所說的亂碼。

一句話:編碼和解碼時用了不同或者不兼容的字符集。

字符

是各種符號和文字的總稱。包括各國家文字、標點符號、圖形符號、數(shù)字等。 字符是一個信息單位,一個數(shù)字是一個字符,一個文字是一個字符,一個標點符號也是一個字符。

字節(jié)

字節(jié)是一個8bit的存儲單元,0~255,根據(jù)字符編碼的不同一個字符可以是單個字節(jié)也可以是多個字節(jié)。

字符集

字符的集合就是字符集。英語可以看成一個字符集,中文可以看成一個字符集,日語也可以看成一個字符集。不同集合支持的字符范圍自然也不一樣,譬如ASCII只支持英文,GB18030支持中文等等。在字符集中,有一個碼表的存在,每一個字符在各自的字符集中對應(yīng)著一個唯一的碼。但是同一個字符在不同字符集中的碼是不一樣的,譬如字符“中”在Unicode和GB18030中就分別對應(yīng)著不同的碼(20013與54992)。

字符編碼

由于計算機只認得電壓高低,所以信息都是以0、1存在計算機里。信息通過轉(zhuǎn)換成二進制比特流就可以在計算機上存儲傳輸。 字符集和字符編碼一般一一對應(yīng)。字符集與字符編碼都是一一對應(yīng)的。但一個例外就是Unicode字符集,它有多種編碼實現(xiàn)(UTF-8,UTF-16,UTF-32等)。

對于一個字符集來說要正確編碼轉(zhuǎn)碼一個字符需要三個關(guān)鍵元素:字庫表(character repertoire)、編碼字符集(coded character set)、字符編碼(character encoding form)。其中字庫表是一個相當于所有可讀或者可顯示字符的數(shù)據(jù)庫,字庫表決定了整個字符集能夠展現(xiàn)表示的所有字符的范圍。編碼字符集,即用一個編碼值code point來表示一個字符在字庫中的位置。字符編碼,將編碼字符集和實際存儲數(shù)值之間的轉(zhuǎn)換關(guān)系。一般來說都會直接將code point的值作為編碼后的值直接存儲。

ASCII

American Standard Code for Information Interchange ,即美國信息互換標準代碼。使用7位二進制共可以表示128個碼位0~127,可表示阿拉伯數(shù)字,大小寫字母,特殊字符。一個字符用一個字節(jié)表示即可。


ASCII表

漢字編碼

GB2312,GBK(GuoBiao KuoZhan),GB18030,都兼容ASCII碼,都用兩個字節(jié)表示,高位低位。

Unicode字符集

Unicode 就是一種編碼字符集,編碼方式可以有多種:UTF-8,UTF-16,UTF-32等

UTF-8編碼

變長的字節(jié)編碼方式(有控制位)。

單字節(jié)字符:0xxx xxxx

如果一個字節(jié)的第一位為0,那么代表當前字符為單字節(jié)字符,占用一個字節(jié)的空間。0之后的所有部分(7個bit)代表在Unicode中的序號。

雙字節(jié)字符:110x xxxx? ? ? ? ? ? 10xx xxxx

如果一個字節(jié)以110開頭,那么代表當前字符為雙字節(jié)字符,占用2個字節(jié)的空間。110之后的所有部分(5個bit)加上后一個字節(jié)的除10外的部分(6個bit)代表在Unicode中的序號。且第二個字節(jié)以10開頭

三字節(jié)字符:1110 xxxx ? ?10xx xxxx ? ? ? 10xx xxxx

如果一個字節(jié)以1110開頭,那么代表當前字符為三字節(jié)字符,占用3個字節(jié)的空間。110之后的所有部分(5個bit)加上后兩個字節(jié)的除10外的部分(12個bit)代表在Unicode中的序號。且第二、第三個字節(jié)以10開頭

多字節(jié)字符:

如果一個字節(jié)以10開頭,那么代表當前字節(jié)為多字節(jié)字符的第二個字節(jié)。10之后的所有部分(6個bit)和之前的部分一同組成在Unicode中的序號。如:

4字節(jié) 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5字節(jié) 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

6字節(jié) 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8 最多可用到6個字節(jié)。

不同字符編碼的轉(zhuǎn)換

如果是相同字符集,由于相同字符集中的碼都是一樣的,所以只需要針對不同的編碼方式轉(zhuǎn)變而已。譬如UTF-16轉(zhuǎn)UTF-8,首先會取到當前需要轉(zhuǎn)換的字符的Unicode碼,然后將當前的編碼方式由雙字節(jié)(有4字節(jié)的拓展就不贅述了),變?yōu)樽冮L的1,2,3等字節(jié)

如果是不同的字符集,由于不同字符集的碼是不一樣的,所以需要各自的碼表才能進行轉(zhuǎn)換。譬如UTF-16轉(zhuǎn)GBK,首先需要取到當前需要轉(zhuǎn)換的字符的Unicode碼,然后根據(jù)Unicode和GBK碼表一一對應(yīng)的關(guān)系(只有部分共同都有的字符才能在碼表中查到),找到它對應(yīng)的GBK碼,然后用GBK的編碼方式(雙字節(jié))進行編碼

對比

GBK 和 UTF-8

1. 區(qū)別:字節(jié)不同

? ? ? ? ? ? ? GBK 中英文統(tǒng)一兩字節(jié)

? ? ? ? ? ? ? UTF-8 英文1個字節(jié),中文3個字節(jié)

2. 區(qū)分:可用 BOM(Byte Order Mark)標記

3. 互換:必須通過 Unicode 編碼

字符集合:GB2312 < GBK < UTF-8

4. 各自的適用場合:

? ? 英文字符多時,用 UTF-8 省空間

? ? 中文多時,用 GBK 省空間

? ? GBK 是中國的,在國家標準 GB2312 基礎(chǔ)上擴充的,通用性差

? ? UTF-8 世界的,國際編碼,通用性好

UTF-32 和 UTF-8

Unicode 只規(guī)定了每個字符的碼點,如何表示則就涉及到了編碼方法。

UTF-32:一個碼點用4個字節(jié)表示,完全對應(yīng) Unicode 編碼(前面加兩字節(jié)的0嘍)

? ? ? ? ? ? ?優(yōu)點:查找效率高

? ? ? ? ? ? 缺點:浪費空間,比相同的 ASCII 編碼文件大四倍。

UTF-8: 是一種變長的編碼方法,字符長度從1個字節(jié)-4個字節(jié)不等。

? ? ? ? ? ? ? ?越常用的字符,字節(jié)越短;

? ? ? ? ? ? ? ?最前面的128個字符,只用1個字節(jié)表示,和ASCII碼完全相同。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容