編碼是將一種文字表示格式轉(zhuǎn)換為另一種格式的過程。這篇文章所講的計(jì)算機(jī)編碼是將人類能看懂的文字轉(zhuǎn)換為計(jì)算機(jī)可以處理的二進(jìn)制'0''1'串的格式的過程。解碼是編碼的逆過程,就是將’0‘’1‘串轉(zhuǎn)換為自然文字的過程。
我們知道,計(jì)算機(jī)不像人能夠看懂不同的文字,他只能處理’0‘’1‘這兩種狀態(tài),這兩種狀態(tài)在計(jì)算機(jī)底層代表了高低電平。所以要使用計(jì)算機(jī)首先得把我們的文字轉(zhuǎn)換為二進(jìn)制串,不同的文字轉(zhuǎn)換為不同的二進(jìn)制串。最初計(jì)算機(jī)科學(xué)家們設(shè)計(jì)了ASCII表,它的全稱是“美國信息交換標(biāo)準(zhǔn)編碼”,最初計(jì)算機(jī)的發(fā)展是從美國開始的,他們也只設(shè)計(jì)了針對他們語言的編碼表。下面這張圖是對應(yīng)的轉(zhuǎn)換表:
基礎(chǔ)的ASCII使用8位二進(jìn)制來表示128個(gè)不同的字符,只使用了后7位,最高位為0。0~31及127(共33個(gè))是控制字符或通信專用字符(其余為可顯示字符),如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BS(退格)、BEL(響鈴)等;
32~126(共95個(gè))是字符(32是空格),其中48~57為0到9十個(gè)阿拉伯?dāng)?shù)字。
65~90為26個(gè)大寫英文字母,97~122號為26個(gè)小寫英文字母,其余為一些標(biāo)點(diǎn)符號、運(yùn)算符號等。
ASCII是最初使用的編碼表,也是現(xiàn)在絕大部分計(jì)算機(jī)都會內(nèi)置的編碼表。當(dāng)我們按下鍵盤上某個(gè)鍵時(shí),鍵盤中的電路會根據(jù)按下的某個(gè)鍵將其轉(zhuǎn)換為ASCII表中的二進(jìn)制串傳給電腦。
ASCII只需要7位就可以將英文表示出來,因?yàn)橛⑽淖帜钢挥?6個(gè),即使大小寫也才52個(gè),加上數(shù)字、標(biāo)點(diǎn)、控制字符等,使用128個(gè)字符編碼就夠了。而中文不一樣,漢字編碼GB_2312收錄了6000多個(gè)漢字,一個(gè)字節(jié)8位最多表示256個(gè)文字,遠(yuǎn)遠(yuǎn)不夠,所以GB_2312使用了2個(gè)字節(jié)來表示漢字,2個(gè)字節(jié)最多可以表示2^16=65536個(gè)文字,所以表示漢字足夠了。
全世界包括很多種語言文字,如果我們在電腦上看某一國文字,沒有相應(yīng)的編碼是看不了的,無法解碼,如果某國語言文字的文章中也包含了其他國家的語言文字或者包括含了英文,那如果不知道他們編碼有區(qū)別的話也不知道何時(shí)去解碼何種文字。為了解決這種問題,Unicode出現(xiàn)了。
Unicode只有一個(gè)字符集,這一個(gè)字符集包括了所有的各國的文字。中、日、韓的三種文字占用了Unicode中0x3000到0x9FFF的部分 Unicode目前普遍采用的是UCS-2,它用兩個(gè)字節(jié)來編碼一個(gè)字符, 比如漢字"經(jīng)"的編碼是0x7ECF,注意字符碼一般用十六進(jìn)制來 表示。編碼從0到127的字符與ASCII編碼的字符一樣,比如字母"a"的Unicode 編碼是0x0061,十進(jìn)制是97,而"a"的ASCII編碼是0x61。Unicode擴(kuò)展自ASCII,ASCII表示了128個(gè)字符,所以Unicode前0-127表示了ASCII的字符。
在Unicode中:漢字“字”對應(yīng)的數(shù)字是23383(十進(jìn)制),十六進(jìn)制表示為5B57。在Unicode中,我們有很多方式將數(shù)字23383表示成程序中的數(shù)據(jù),包括:UTF-8、UTF-16、UTF-32。UTF是“Unicode Transformation Format”的縮寫,可以翻譯成Unicode字符集轉(zhuǎn)換格式,即怎樣將Unicode定義的數(shù)字轉(zhuǎn)換成程序數(shù)據(jù)。所以Unicode定義了表示各種文字的數(shù)字編碼,實(shí)際實(shí)現(xiàn)時(shí)占用幾個(gè)字節(jié),怎么實(shí)現(xiàn)出來還得根據(jù)采用的UTF來進(jìn)行轉(zhuǎn)換。
UTF-8以字節(jié)為單位對Unicode進(jìn)行編碼。從Unicode到UTF-8的編碼方式如下:
Unicode編碼(十六進(jìn)制) | UTF-8 字節(jié)流(二進(jìn)制) |
000000-00007F | 0xxxxxxx |
000080-0007FF | 110xxxxx 10xxxxxx |
000800-00FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
010000-10FFFF | 11110xxx10xxxxxx10xxxxxx10xxxxxx |
UTF-8的特點(diǎn)是對不同范圍的字符使用不同長度的編碼。對于0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是6個(gè)字節(jié)。從上表可以看出,6字節(jié)模板有31個(gè)x,即可以容納31位二進(jìn)制數(shù)字。Unicode的最大碼位0x7FFFFFFF也只有31位。
例1:“漢”字的Unicode編碼是0x6C49。0x6C49在0x0800-0xFFFF之間,使用用3字節(jié)模板了:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進(jìn)制是:0110 1100 0100 1001, 用這個(gè)比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。
在使用電腦的時(shí)候如果出現(xiàn)了亂碼問題,應(yīng)該就是采用的編碼格式不一致造成的,確定原始文檔采用的編碼格式,再選擇相應(yīng)的編碼進(jìn)行解碼打開就會解決這種問題。編程時(shí),如果數(shù)據(jù)庫存儲時(shí)出現(xiàn)了亂碼或者讀取文件時(shí)出現(xiàn)了亂碼,那也應(yīng)該確定原始文本編碼格式和數(shù)據(jù)庫表編碼格式或者代碼中指定的編解碼是否一致,從而解決這種問題。