一直被字符的編碼搞得頭暈腦脹,經常出現(xiàn)亂碼卻又無可奈何,最近看到兩篇講字符編碼的文章,這才有點頭緒,于是決定把它寫出來。
位與字節(jié)
計算機是以二進制位進行存儲的,8位構成一字節(jié),那么就會引來一個問題,就是如何將現(xiàn)實生活中真正的字符(如'a'、'b'、'c'等)轉為二進制位放到計算機中進行存儲。因此字符編碼也就應運而生了,即定義一些規(guī)范,將真實字符與二進制位聯(lián)系起來。又因為計算機的內存是以字節(jié)為單位的,所以也就是將真實字符與字節(jié)聯(lián)系起來。
字符集發(fā)展
最開始使用的是ASCII碼字符集,用一個字節(jié)來表示就足夠了(其實只用了7為二進制數(shù)),共128個字符,95的可打印字符(如'a'、'b'等),33個控制字符(如'\n'、'\t'等),ASCII碼字符集基本滿足了美國人民的需要。但是對于歐洲人民來說,這個字符集就不夠用了,因為他們經常會用到一些擴展的拉丁字符(如'?'等),怎么辦呢?
最簡單的辦法就是將一個字節(jié)的8位全部用上,于是又了EASCII字符集,共256個字符,這滿足了西歐人民的需要,但是對于北歐和東歐的人民來講,仍然不夠用,于是ISO 8859字符集出現(xiàn)了,它共由15個字符集組成,如ISO 8859-1為西歐字符集,ISO 8859-4為北歐字符集等。如此一來,歐洲人民的字符問題就解決了。
終于到我們大天朝了,中文字符數(shù)量太多,還分為簡體和繁體兩種。于是不得不采用兩個字節(jié)進行存儲,于是出現(xiàn)了以下幾種字符集:
| 字符集 | 字節(jié)數(shù) | 兼容性 | 說明 |
|---|---|---|---|
| GB2312 | 變字節(jié),1-2 | 兼容ASCII(1字節(jié)) | 簡體中文字符集 |
| BIG5 | 定字節(jié),2 | 兼容ASCII(2字節(jié)) | 繁體中文字符集 |
| GBK | 定字節(jié),2 | 兼容ASCII(2字節(jié)) | GB2312的擴展(支持繁體) |
Unicode
上面說了每個區(qū)域有各自的字符集標準,那么就無法再同一個文檔中同時顯示所有的字符,于是有人開始琢磨能不能把規(guī)定一個全球性的字符集標準,能夠將世界上的所有字符都包括進去,因此有了Unicode字符集,它規(guī)定使用4個字節(jié)進行存儲,包括了世界上所有的字符,并且可以擴展。但是用四個字節(jié)存儲ASCII碼浪費了太多存儲空間,因此剛開始的時候Unicode難以得到推廣,所以必須采用有效的編碼方案。
可以這樣說,上面講的所有字符集都是把字符集(不包括Unicode)與編碼方案緊密結合起來的,也就是每個字符都有確定的字節(jié)流(二進制位),因此GBK即可稱為字符集,也可稱為編碼方案。但是可以說Unicode只是單純的字符集,里面只有字符及其字符所對應的字符碼。至于編碼方案,有UTF-8,UTF-16,GB18030等。
UTF-8
UTF-8是目前使用最多的編碼方案,其實更準確地說是Unicode的編碼方案,主要有兩條規(guī)則:
- 對于單字節(jié)字符,字節(jié)的首位二進制碼為0,其余為Unicode碼
- 對于n(2-4)字節(jié)字符,首字節(jié)的前n位二進制碼為1,n+1位二進制碼為0,后面字節(jié)的兩位二進制碼均為10,其余為Unicode碼
具體如下表:
| Unicode(16進制) | UTF-8(二進制) |
|---|---|
| 00000000 - 0000007F | 0xxxxxxx |
| 00000080 - 000007FF | 110xxxxx 10xxxxxx |
| 00000800 - 0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
如此一來,問題就得到解決了,UTF-8也得到了迅速發(fā)展。
注意事項
- ANSI:為Windows下默認的編碼方案,對英文使用ASCII碼,對中文使用GB2313編碼方案
- BOM:微軟用它來標識采用UTF-8編碼方案的文件,并不是通用標準
- 亂碼:亂碼的根本原因是使用錯誤的編碼方案去解碼字節(jié)流,因此當出現(xiàn)亂碼的時候,請去查看文件的編碼方案是什么,這樣才能根本解決亂碼
參考