字符,字符集,字符编码
字符,字符集,字符編碼 簡書郭文圣
?
現在Unicode已然一統天下,我想很多年輕的程序員可能都沒遇到過編碼問題,更不用說了解編碼的發展了。前些日子在一個老網站上偶遇亂碼,雖然入行時間不短,但對其究竟也是不甚了解,好奇心驅使下落入深坑。還好經過一段時間的摸爬滾打,邊學邊寫,總算大概理清了個脈絡,記錄之,分享之。
概念
字符是一個信息單位,在計算機里面,一個中文漢字是一個字符,一個英文字母是一個字符,一個阿拉伯數字是一個字符,一個標點符號也是一個字符。
字符集是字符組成的集合,通常以二維表的形式存在,二維表的內容和大小是由使用者的語言而定,是英語,是漢語,還是阿拉伯語。
字符編碼是把字符集中的字符編碼為特定的二進制數,以便在計算機中存儲。編碼方式一般就是對二維表的橫縱坐標進行變換的算法。一般都比較簡單,直接把橫縱坐標拼一起就完事了。后來隨著字符集的不斷擴大,為了節省存儲空間,才出現了各種各樣的算法。
字符集和字符編碼一般都是成對出現的,如ASCII、IOS-8859-1、GB2312、GBK,都是即表示了字符集又表示了對應的字符編碼,以后統稱為編碼。Unicode比較特殊,具有UCS-4、UTF-8、UTF-16、UTF-32等編碼。
發展
單字節
計算機是美國人發明的,人家用的是美式英語,字符比較少,所以一開始就設計了一個不大的二維表,128個字符,取名叫ASCII(American Standard Code for Information Interchange)。128個碼位,用7位二進制數表示,由于計算機1個字節是8位二進制數,所以最高位為0,即00000000-01111111或0x00-0x7F。
ASCII
后來美國人發現128個碼位不夠用,于是在原來二維表的基礎上進行了擴展,256個字符,取名叫EASCII(Extended ASCII)。256個碼位,用8位二進制數表示,即00000000-11111111或0x00-0xFF。
EASCII
當計算機傳到了歐洲,美國人的標準不適用了,但是改改還能湊合。于是國際標準化組織在ASCII的基礎上進行了擴展,形成了ISO-8859標準,跟EASCII類似,兼容ASCII,在高128個碼位上有所區別。但是由于歐洲的語言環境十分復雜,所以根據各地區的語言又形成了很多子標準,ISO-8859-1、ISO-8859-2、ISO-8859-3、……、ISO-8859-16,真是令人發指。
雙字節
當計算機傳到了亞洲,尤其是東亞,國際標準被秒殺了,路邊小孩隨便說句話,256個碼位就不夠用了。于是乎繼續擴大二維表,單字節改雙字節,16位二進制數,65536個碼位。在不同國家和地區又出現了很多編碼,大陸的GB2312、港臺的BIG5、日本的Shift JIS等等。
注意65536個碼位這種說法只是理想情況,由于雙字節編碼可以是變長的,也就是說同一個編碼里面有些字符是單字節表示,有些字符是雙字節表示。這樣做的好處是,一方面可以兼容ASCII,另一方面可以節省存儲容量,代價就是會損失一部分碼位。而且編碼的設計也并不是想象的那樣,所有字符從頭到尾布滿整個二維表,都是有預留空間的。比如說GBK是GB2312的擴展(K竟然是拼音KuoZhan的縮寫),按理說都屬于雙字節編碼,碼位是一樣的,根本談不上擴展,但實際上是預留空間在起作用。比如下圖為GBK的編碼空間,GBK/1、GBK/2是GB2312的區域,GBK/3、GBK/4、GBK/5是GBK的區域,紅色是用戶自定義區域,白色可能就是由于變長編碼損失的區域了。
GBK
Unicode
當互聯網席卷了全球,地域限制被打破了,不同國家和地區的計算機在交換數據的過程中,就會出現亂碼的問題,跟語言上的地理隔離差不多。亂碼是怎么出現的呢?對同一組二進制數據,不同的編碼會解析出不同的字符,用對了編碼,解析出來的字符組成的文字是有意義的,用錯了編碼,解析出來的字符組成的文字是沒意義的,也就是通常所說的亂碼。
經過之前的介紹,編碼很多,全球的計算機們沒辦法在一起好好的玩耍。要徹底解決這個問題,替代原先基于語言的編碼系統,就需要一個通用的字符集UCS(Universal Character Set)和一個通用的字符編碼Unicode。一開始UCS用2個字節表示,叫做UCS-2,后來2個字節不夠用,于是就用4個字節,叫做UCS-4。但是如果每一個字符都用4個字節來表示的話,相較之前的編碼會浪費很多存儲空間,尤其是相對ASCII等單字節編碼會非常吃虧。并且當時已經有些廠商在雙字節編碼上投入了很大的精力。于是UTF-16就被作為一種折中的方案提了出來,既保持了兩字節不變,又保證了足夠的編碼空間。而UTF-32是與UCS-4相對應的,UTF-8則由于擴展性比較強,從容應對了UCS-2到UCS-4的改變。關于各種UTF的實現細節可以點擊鏈接查看(FQ),已經說得很清楚了,就不贅述了,但不得不提一下,UTF-16的設計還挺巧妙的。
UTF(Unicode Transformation Format)是將Unicode編碼進行轉換為字節序列(這也意味著所有的ASCLL字節序列用ASCLL碼表示和用UTF表示是一樣的),通常會在存儲空間和效率上進行一定的權衡,有很多種實現方式,前面提到了UTF-8和UTF-16是最常用的。這就是之前提到的Unicode的特殊之處。
歷史
-
ASCII
1960 開發
1963 發布
1986 最后一次更新 -
ISO-8859-1
1998 發布 -
GB2312
1980 發布 -
GBK
1993 發布 -
UCS-2
In the late 1980s -
Unicode
1987 開發
1991 發布
1996 實現代理機制(UTF-16)
2015 最新版8.0 -
UTF-8
1993 發布
2008 流行 -
UTF-16
1996 開發
2000 發布
根據以上各個編碼發展的一些時間節點,再配合下圖UTF-8制霸互聯網過程,會有一個比較清晰的了解。
UTF-8
尾聲
雖然Unicode解決了地球上的問題,但是以后三體人入侵可怎么辦,根據這些天研究編碼發展歷史來看,比較靠譜的回答——還是到時再說吧。
?
參考:關于常用的字符集和編碼? ? (一個好看的故事)
轉載于:https://www.cnblogs.com/yweihum/p/7394738.html
總結
以上是生活随笔為你收集整理的字符,字符集,字符编码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【每日一题】4月9日题目精讲 Runni
- 下一篇: 树学