字元編碼那些事兒
Unicode,ASCII,UTF-8,GB2312......這些到底是什麼?為什麼vim開啟編輯文件出現亂碼?怎麼修改字元編碼之後就解決了?
很多與文件編輯有關的軟體,也總是涉及到設定字元編碼的選項?應該怎麼設定?
讓我們帶著疑問一步一步撥雲見日。
1、為什麼要有字元編碼?
計算機系統中所有資訊以二進位制形式儲存,因此為了將我們日常所用的字元轉化為計算機內部的資訊,需要通過字元編碼將這些字元轉化為二進位制碼。那麼這裡涉及到兩個概念:
字符集:字符集就是用十進位制來表示各種字元的集合。
字元編碼:將字元轉化為二進位制編碼的規則。
2、為什麼會有多種編碼方式?
ASCII
最早,ASCII(American standard Code for information Interchange)作為美國人發明的字元編碼方式,其字符集包括128個字元(0-127號),由8位二進位制表示,其中最前面一位統一規定為0,後7位用來表示這些字元。比如‘A’在字符集中是65,表示為二進位制是01000001。
但後來當世界各地都開始用計算機時他們的字母裡很多是ASCII裡面沒有,因此將ASCII碼中127號之後的空位來表示這些新字元,因此從128-255這一頁字符集被稱為擴充套件字符集。
GB2312
等到中國人使用計算機後,發現完全沒有中文字元啊,怎麼辦?於是中國人提出的字元編碼方案為GB2312,相當於對ASCII的擴充套件。小於等於127號的繼續使用,並且用2個大於127的位元組表示一箇中文字元,前面的一個位元組(他稱之為高位元組
)從0xA1用到 0xF7,後面一個位元組(低位元組
)從0xA1到0xFE,這樣我們就可以組合出大約7000多個簡體漢字了。在這些編碼中,還把數學符號,羅馬希臘的字母,日文的假名都編進去了,連ASCII裡本來就有的數字,標點,字母都統統重新編了兩個位元組長的編碼,這就是常說的“全形
GBK
但是中文還是不夠用,很多冷門生僻字和繁體字等還是無法識別怎麼辦?於是要求高位元組大於127的就認為是2位元組的中文字元,這樣結果脫戰之後就是GBK標準。GBK相比GB2312,增加了近20000個新漢字與符號。但後來少數民族同胞也要用計算機,於是為了擴充套件少數民族字元,GBK被擴充套件為GB18030。這些編碼標準統稱為DBCS(Double Byte Character Set,雙位元組字符集)。
Unicode與UTF-8/UTF-16
為了方便全世界的文化交流,滿足跨語言、跨平臺文字轉換、處理需求,ISO(國際標準化組織)決定製定一個統一的包括全世界所有字元的編碼標準,包括字符集、編碼方案等,他們打算叫他"Universal Multiple-Octet Coded Chracter Set",簡稱UCS,俗稱Unicode。
在Unicode中,直接規定必須用兩個位元組,ASCII那些半形字元,保持原編碼不變,只是將其長度由原來的8位擴充套件為16位(高8位全為0),而其他文化和語言的字元則全部重新統一編碼。
問題是:(1)計算機怎麼知道2個位元組為一個字元,如何識別2個位元組為一個字元?(2)半形字元如果用兩個位元組表示,很浪費空間,而計算機大部分內容還是英文。
而作為Unicode字符集的一種編碼方式,UTF-8採用變長編碼,使用1-4個位元組表示一個字元,其特點是,對不同範圍的字元使用不同長度的編碼。
UTF-8的編碼規則:
(1)單位元組符號,位元組的第一位設為0,後面7位為這個符號的Unicode碼。因此對於英文字母,UTF-8編碼和ASCII碼是相同的。
(2)對於n位元組的符號(n>1),第一個位元組的前n位都設為1,第n+1位設為0,後面位元組的前兩位一律設為10,剩下的沒有提及的二進位制位,全為這個符號的unicode碼。
類似的,UTF-16使用二位元組或四位元組表示一個字元的變長編碼。
3、為什麼會出現亂碼?
編碼方式不相容會導致亂碼,例如當一個檔案採用編碼A的方式編碼,但按照編碼B的方式解碼,必然得到亂碼。
參考資料: