在計算機(jī)的內(nèi)部件豌,所有的數(shù)據(jù)和指令都是以二進(jìn)制形式來表示的。為了表示常用的字母漢字等各種符號托嚣,于是用特定的二進(jìn)制序列來表示特定的字符檩帐。當(dāng)在使用字符的場景中遇到這這些特定的二進(jìn)制序列時,就轉(zhuǎn)義為指定的字符元咙,這就是字符編碼梯影。
ASCII
ASCII(American Standard Code for Information Interchange,美國信息交換標(biāo)準(zhǔn)代碼)庶香,是由美國國家標(biāo)準(zhǔn)學(xué)會(ANSI)制定的甲棍,于1967發(fā)表,是第一個正式的計算機(jī)編碼赶掖。ASCII碼采用一個字節(jié)進(jìn)行編碼感猛,使用了除最高位外的7位(最高位為總是0),一共定義了128個字符奢赂。
- 00-1F以及7F:共33個字符為控制字符是無法顯示的陪白。
- 20-7E:為可顯示的數(shù)字英文和一些常用的符合。
GB2312
ASCII只定義了128個字符膳灶,但對于含有進(jìn)10萬漢字的中文來說明顯是不夠的咱士。為了在計算機(jī)上使用中文,中國國家標(biāo)準(zhǔn)總局1980年發(fā)布GB2312編碼。
GB2312使用兩個字節(jié)進(jìn)行編碼序厉。第一個字節(jié)稱為“高位字節(jié)”锐膜,第二個字節(jié)稱為“低位字節(jié)”,“高位字節(jié)”范圍為0xA1–0xF7脂矫,“低位字節(jié)”范圍為0xA1–0xFE枣耀。同時為了兼容ASCII碼GB2312保留了一個字節(jié)的ASCII碼,所以在GB2312編碼的文件中同時存在一個字節(jié)的ASCII碼和兩個字節(jié)的GB2312碼庭再。
GB2312的第一個和第二個字節(jié)都是從A1(10100001)開始的捞奕,可以看出GB2312的字節(jié)碼都是1開始的,所以當(dāng)遇到0開始的字節(jié)時就是ASCII碼拄轻。
GB2312將定義的字符劃分為94個區(qū)颅围,字符所在的區(qū)稱為區(qū)碼,在區(qū)中的位置稱為位碼恨搓。字符的高字節(jié)編碼減去A0就是區(qū)碼院促,低字節(jié)減去A0就是位碼。例如‘啊'字的字節(jié)碼為B0A1斧抱,高字節(jié)B0減去A0得到16, 低字節(jié)A1減去A0得到1常拓,‘啊’的去罵和位碼就是16和1。
相應(yīng)的也可以通過字符的區(qū)碼和位碼分別加上A0得到字符的字節(jié)碼辉浦。
GB2312除了定義6萬多個中文弄抬,還定義一些常見的繁體字、日文和希臘字母等一些符合宪郊。在兼容ASCII碼的時也對ASCII碼的字符定義了兩個字節(jié)的表示掂恕,輸入法中全角就是指輸入時用兩個字節(jié)的定義,半角則指用一個字節(jié)的ASCII碼弛槐。
GBK:
GB2312碼雖然定義6萬多個字符懊亡,但對于一些生僻的字,如“啰”乎串,“镕“”以及一些繁體字等并沒有定義到店枣。為了支持更多的字符,在GB2312的基礎(chǔ)上擴(kuò)展制定了GBK碼灌闺。GBk完全兼容GB2312艰争。
GBK碼將第一個字節(jié)的定義范圍擴(kuò)展到81–FE,第二字節(jié)的一部分在40–7E中桂对,另一部分在80–FE中,使用了GB2312未使用到的字節(jié)來進(jìn)行擴(kuò)展鸠匀,也就是在GB2312中定義的字符在GBK中定義仍然相同蕉斜。同時繼續(xù)兼容一個字節(jié)的ASCII碼。
GBK定義了2萬多個符號。
GB18030:
雖然GBK定義了兩萬多個字符宅此,但我們漢字可是接近十萬的机错,在加上其他字符顯然GBK碼也不夠用了,所以在2000年我國頒布了GB18030編碼父腕,并在2005進(jìn)行了一次補(bǔ)充弱匪。
GB18030兼在容GBK碼的同時對于新的字符使用四個字節(jié)進(jìn)行編碼。新的四個字節(jié)的字符不和GBK中已經(jīng)定義了的字符沖突璧亮,GBK中定義了的字符仍然使用2個字節(jié)萧诫,ASCII嗎仍然使用一個字節(jié)。
Unicode:
世界上有很多的語言枝嘶,許多其他地區(qū)也定義了自己的編碼方式帘饶,并且這些編碼多數(shù)是互不兼容的,比如同是中文但‘好‘’字在GBK中定義為BAC3群扶,而在臺灣的BIG5編碼中定義為A66E及刻。
為了統(tǒng)一各個語言和符號的編碼定義,誕生了Unicode碼竞阐。Unicode為世界上絕大多數(shù)語言和符號制定了編碼缴饭,目前已經(jīng)收錄超過13萬個字符。發(fā)展由非營利機(jī)構(gòu)統(tǒng)一碼聯(lián)盟負(fù)責(zé)骆莹。
Unicode只定義了各個字符的編碼值颗搂,它并不是一個具體的實現(xiàn)。比如‘好’字Unicode定義編碼為597D汪疮,但597D這個值在實際中是用三個字節(jié)還是四個字節(jié)表示峭火,Unicode并未定義。
UTF-8:
UTF-8是對Unicode定義的編碼的一種實現(xiàn)智嚷。UTF-8使用一至六個字節(jié)的可變長字符編卖丸。字符的字節(jié)數(shù)由最高位連續(xù)的1的個數(shù)來決定。例如‘好‘的UTF-8二進(jìn)制碼為11100101 10100101 10111101盏道,最高位有三個連續(xù)的1所以該字符有三個字節(jié)稍浆。
UTF-8是如何表示Unicode定義的值的?
UTF-8中最高位連續(xù)的1的個數(shù)表示字節(jié)數(shù)猜嘱。后面的字節(jié)都以10開頭衅枫,其余的位用Unicode碼的值填充。如果Unicode碼的值不夠填充則在第一個字節(jié)1的后面補(bǔ)充0朗伶。如下‘好’字的Unicode碼與utf-8碼:
utf-8使用三個字節(jié)來編碼中文弦撩,所以對于中文utf-8比gbk要多50%的空間。
ISO-8859-1
又名latin1论皆,使用一個字節(jié)來編碼是對ASCII的補(bǔ)充益楼。其編碼范圍是0x00-0xFF猾漫,其中0x00-0x7F之間和ASCII碼完全一致。
因為ISO-8859-1是使用單個字節(jié)來編碼的感凤,所以但使用其存儲其他方式編碼的內(nèi)容時雖然會亂碼但是并不會改變保存內(nèi)容的實際值悯周。利用這個特性,MySQL數(shù)據(jù)庫默認(rèn)編碼使用Latin1陪竿,在存儲其他編碼的字符時不會造成內(nèi)容的丟失和改變禽翼。