說到ASCII,Unicode和UTF-8,可能大家都知道是字符編碼,但具體含義,以及其中差異,可能很多人都不知道。
一、名稱解釋
ASCII:American Standard Code for Information Interchange,美國信息互換標(biāo)準(zhǔn)代碼。Unicode:統(tǒng)一碼、萬國碼、單一碼,是計(jì)算機(jī)科學(xué)領(lǐng)域里的一項(xiàng)業(yè)界標(biāo)準(zhǔn),包括字符集、編碼方案等。UTF-8:8-bit Unicode Transformation Format,是一種針對(duì)Unicode的可變長度字符編碼。
二、歷史變遷
很久以前,有一群人,他們決定用8個(gè)可以開合的晶體管來組合成不同的狀態(tài),以表示世界上的萬物。他們看到8個(gè)開關(guān)狀態(tài)是好的,于是他們把這稱為“字節(jié)”。再后來,他們又做了一些可以處理這些字節(jié)的機(jī)器,機(jī)器開動(dòng)了,可以用字節(jié)來組合出很多狀態(tài),狀態(tài)開始變來變?nèi)?。他們看到這樣是好的,于是它們就這機(jī)器稱為”計(jì)算機(jī)“。開始計(jì)算機(jī)只在美國使用,八位的字節(jié)一共可以組合出256種不同的狀態(tài)。他們把其中的編號(hào)從0開始的32種狀態(tài)分別規(guī)定了特殊的用途,一但終端、打印機(jī)遇上約定好的這些字節(jié)被傳過來時(shí),就要做一些約定的動(dòng)作。遇上0×10, 終端就換行,遇上0×07, 終端就向人們嘟嘟叫。他們看到這樣很好,于是就把這些0×20以下的字節(jié)狀態(tài)稱為“控制碼”。他們又把所有的空格、標(biāo)點(diǎn)符號(hào)、數(shù)字、大小寫字母分別用連續(xù)的字節(jié)狀態(tài)表示,一直編到了第127號(hào),這樣計(jì)算機(jī)就可以用不同字節(jié)來存儲(chǔ)英語的文字了。大家看到這樣,都感覺很好,于是大家都把這個(gè)方案叫做 ANSI 。后來,世界各地都開始使用計(jì)算機(jī)了,但是很多國家用的不是英文,他們的字母里有許多是ASCII里沒有的,為了可以在計(jì)算機(jī) 保存他們的文字,他們決定采用 127號(hào)之后的空位來表示這些新的字母、符號(hào),還加入了很多畫表格時(shí)需要用下到的橫線、豎線、交叉等形狀,一直把序號(hào)編到了最后一個(gè)狀態(tài)255。從128 到255這一頁的字符集被稱“擴(kuò)展字符集”。等中國人們得到計(jì)算機(jī)時(shí),已經(jīng)沒有可以利用的字節(jié)狀態(tài)來表示漢字,而且常用漢字有六七千個(gè),這個(gè)時(shí)候,中國人民就使用了一套漢字方案叫做GB2312”。隨著發(fā)展,又發(fā)現(xiàn)了一些局限,所以就有了GBK,再繼續(xù)往后增加了一些字符(如少數(shù)名族字體),GBK擴(kuò)成了 GB18030。
因?yàn)楫?dāng)時(shí)各個(gè)國家都像中國這樣搞出一套自己的編碼標(biāo)準(zhǔn),結(jié)果互相之間誰也不懂誰的編碼,誰也不支持別人的編碼,連大陸和臺(tái)灣這樣只相隔了150海里也使用不同編碼。這個(gè)時(shí)候,出現(xiàn)了一個(gè)叫 ISO 組織(國際標(biāo)準(zhǔn)化組織)決定著手解決這個(gè)問題。他們采用的方法很簡(jiǎn)單:廢了所有的地區(qū)性編碼方案,重新搞一個(gè)包括了地球上所有文化、所有字母和符號(hào) 的編碼!他們打算叫它“Universal Multiple-Octet Coded Character Set”,簡(jiǎn)稱 UCS, 俗稱 “Unicode”。
但是Unicode同樣也有2個(gè)問題:
1.計(jì)算機(jī)怎么知道二個(gè)字節(jié)為一個(gè)字符,如何識(shí)別二個(gè)字節(jié)為什么一個(gè)字符?
2.針對(duì)英文字符,如果使用大于1個(gè)字節(jié)來表示,那么低位的前面幾個(gè)字節(jié)全是0。很奢侈浪費(fèi)空間,因?yàn)楝F(xiàn)在計(jì)算機(jī)大部分內(nèi)容還是英文。
unicode在很長一段時(shí)間內(nèi)無法推廣,直到互聯(lián)網(wǎng)的出現(xiàn),為解決unicode如何在網(wǎng)絡(luò)上傳輸?shù)膯栴},于是面向傳輸?shù)谋姸?nbsp;UTF(UCS Transfer Format)標(biāo)準(zhǔn)出現(xiàn)了。顧名思義,UTF-8就是每次8個(gè)位傳輸數(shù)據(jù),而UTF-16就是每次16個(gè)位。UTF-8就是在互聯(lián)網(wǎng)上使用最廣的一種unicode的實(shí)現(xiàn)方式,這是為傳輸而設(shè)計(jì)的編碼,并使編碼無國界,這樣就可以顯示全世界上所有文化的字符了。
三、Charset and Encoding
Charset (Character set) 字符集:是對(duì)字符抽象表示的集合。包括世界上各種文字、符合和字符。字符集只是一個(gè)規(guī)則集合的名字,對(duì)應(yīng)到真實(shí)生活中,字符集就是對(duì)某種語言的稱呼。例如:英語,漢語,日語。對(duì)于一個(gè)字符集來說要正確編碼轉(zhuǎn)碼一個(gè)字符需要三個(gè)關(guān)鍵元素:字庫表(character repertoire)、編碼字符集(coded character set)、字符編碼(character encoding)。
字庫表是一個(gè)相當(dāng)于所有可讀或者可顯示字符的數(shù)據(jù)庫。字庫表決定了整個(gè)字符集能夠展現(xiàn)表示的所有字符的范圍。編碼字符集,即用一個(gè)編碼值code point來表示一個(gè)字符在字庫中的位置。字符編碼,將編碼字符集和實(shí)際存儲(chǔ)數(shù)值之間的轉(zhuǎn)換關(guān)系。
四、UTF-8和Unicode的關(guān)系
看完上面兩個(gè)概念解釋,相信你應(yīng)該明白其中關(guān)系了。Unicode就是上文中提到的編碼字符集,而UTF-8就是字符編碼,即Unicode規(guī)則字庫的一種實(shí)現(xiàn)形式。隨著互聯(lián)網(wǎng)的發(fā)展,對(duì)同一字庫集的要求越來越迫切,Unicode標(biāo)準(zhǔn)也就自然而然的出現(xiàn)。它幾乎涵蓋了各個(gè)國家語言可能出現(xiàn)的符號(hào)和文字,并將為他們編號(hào)。
五、進(jìn)一步理解UTF-8編碼
UTF-8編碼為變長編碼。最小編碼單位(code unit)為一個(gè)字節(jié)。一個(gè)字節(jié)的前1-3個(gè)bit為描述性部分,后面為實(shí)際序號(hào)部分。
1.如果一個(gè)字節(jié)的第一位為0,那么代表當(dāng)前字符為單字節(jié)字符,占用一個(gè)字節(jié)的空間。0之后的所有部分(7個(gè)bit)代表在Unicode中的序號(hào)。
2.如果一個(gè)字節(jié)以110開頭,那么代表當(dāng)前字符為雙字節(jié)字符,占用2個(gè)字節(jié)的空間。110之后的所有部分(5個(gè)bit)加上后一個(gè)字節(jié)的除10外的部分(6個(gè)bit)代表在Unicode中的序號(hào)。且第二個(gè)字節(jié)以10開頭。
3.如果一個(gè)字節(jié)以1110開頭,那么代表當(dāng)前字符為三字節(jié)字符,占用3個(gè)字節(jié)的空間。110之后的所有部分(5個(gè)bit)加上后兩個(gè)字節(jié)的除10外的部分(12個(gè)bit)代表在Unicode中的序號(hào)。且第二、第三個(gè)字節(jié)以10開頭。
來看一個(gè)UTF-8編碼例子:
1個(gè)字節(jié)的UTF-8十六進(jìn)制編碼是以比8小的數(shù)字開頭的2個(gè)字節(jié)的UTF-8十六進(jìn)制編碼是以C或D開頭的3個(gè)字節(jié)的UTF-8十六進(jìn)制編碼是以E開頭的