字符集(charset)和字元編碼(character encoding)是兩個含義相近的概念。在歷史上一段時間裡,二者實際上指代同乙個東西,就是為字元建立的數字編號。字符集建立了字元到數字的1-1對映。對於每個字元,都有唯一的數字與之相對應。對映的作用域是字符集能夠識別的全部字元,值域是這些字元的數字編號。字元編碼則是在字符集的基礎上更進一步,規定了在計算機中如何表示這些數字編號。比如我們可以把字元「a」對映成65,這就是乙個字符集(雖然只包含1個字元)。現在考慮我們如何在計算機中表示數字65。假設我們使用c語言,我們可以用char、short、int、long這4種資料型別記錄數字65,因此產生了這個小小字符集的4種不同的字元編碼。
char a_c = 0x41;
short a_s = 0x0041;
int a_i = 0x00000041;
long a_l = 0x0000000000000041;
一些字符集在編制的時候,就規定了數字編號的表示方式。對於這種情況,字符集和字元編碼是等同的。
最初每個計算機廠商都設計了自己的字元編碼。為了讓不同廠商的系統可以相互通訊,統一字元編碼的需求產生了。最開始統一的是表示拉丁字母的ascii碼。拉丁字母數量較少,因此ascii採用單位元組編碼。單位元組可以表示256個不同的字元,這對於象形文本是遠遠不夠的。因此產生了雙位元組字符集dbcs(double-byte character set)。dbcs用兩個位元組記錄字元的編號,最多支援65536個字元。如果只考慮常用字元,對於大部分文字,dbcs已經足夠用了。
廠商希望將軟體銷售到不同的地區,因此希望軟體能夠支援多種文字。這個就要求建立乙個支援多種文字的字符集。國際標準化組織iso和unicode聯盟分別著手進行這項工作。iso製作的字符集叫做ucs(universal character set),通過標準iso 10646進行規範。unicode聯盟編制的字符集叫做unicode。隨著工作的進行,兩個組織認識到建立統一字符集的重要性,並著手合併工作成果,這就是今天大家看到的unicode(嚴格來說是unicode 2.0及以後版本)。如今ucs和unicode可以認為是等同的。iso為ucs定義了兩種字元編碼,分別使用2位元組和4位元組記錄字元編號,因此稱為ucs-2和ucs-4。unicode聯盟為unicode定義了3種字元編碼,分別是utf-8、utf-16和utf-32。utf-16和utf-32可以看做和ucs-2、ucs-4是等同的。utf-8則採用變長編碼,編碼長度可以是1、2、3或4位元組。變長編碼的優點有2個:可以相容ascii,對於包含拉丁字元較多的文字,編碼的總長度較小。當然定長編碼也有自己的優勢:解析簡單,使用方便。
編碼長度
字元範圍
utf-8編碼
10x000000~0x00007f
0******x
20x000080~0x0007ff
110***xx 10******
30x000800~0x00ffff
1110***x 10****** 10******
40x010000~0x10ffff
11110*** 10****** 10****** 10******
對於多位元組定長編碼,需要考慮位元組序的問題。因此utf-16和utf-32又被分為utf-16le、utf-16be、utf-32le、utf-32be。為了確定位元組序,unicode引入了bom(byte order mask)。bom是編碼首部的幾個位元組,是可選的。
utf-8
0xef 0xbb 0xbf
utf-16le
0xff 0xfe
utf-16be
0xfe 0xff
utf-32le
0xff 0xfe 0x00 0x00
utf-32be
0x00 0x00 0xfe 0xff
國內常用的字符集/字元編碼有:
這是**經常出現的亂碼。unicode有乙個特殊符號0xfffd,用於替換無法識別的字元。假設乙個html頁面採用gbk編碼。web應用在讀取html時,卻以unicode進行解碼,其中有些無法解析的字元就會被0xfffd替換。當傳輸給客戶端時,如果採用了utf-8編碼,0xfffd將編碼為0xef 0xbf 0xbd。而「錕斤拷」三個子的gbk編碼是 0xef 0xbf 0xbd 0xef 0xbf 0xbd。
為了提供相容和擴充套件,字符集通常會預留一部分編號,供使用者自行約定用途。這部分編號叫做pua(private user areas)。在字符集的後續版本中,保證不會使用pua中的編號。gbk和unicode都有pua。假設在字符集版本1中,缺少了字元x。使用者在pua中為x分配了編號charset_1_pua(x)。在字符集版本2中,增加了字元x,並分配了編號charset_2(x),就會出現乙個字元擁有兩個編碼的情況。如果乙個計算機系統使用字符集版本1,另乙個使用字符集版本2,它們在通訊的時候,就會出現無法識別字元x的情況。
為了推進電子政務建設,2023年公安部委託北大方正公司建立生僻字庫,叫做方正人口資訊字型檔(包括字型和輸入法)。為了處理當時gbk和unicode尚未支援的生僻字,方正人口資訊字型檔使用了大量的pua編碼,包括4700多個unicode pua編碼和1400多個gbk pua編碼。其中一些字元被新增到後續的unicode版本中,因此出現了一字雙碼的情況。在新系統上生成的,包含一字雙碼字元的資料,在老的系統上無法識別。這裡面最著名的,當屬「龑」字。
字符集和字符集編碼詳解
gb2312 gbk ascii asni unicode utf 8等等,這些字眼非常常見,同時帶來許多的問題。本文只是從理解的角度,說明以上內容的不同含義從而達到區分其用法的目的是夠了的。至於實現方式,可以查閱各自的詳細標準官方文件。先解釋乙個概念,什麼是字符集,嗯,不解釋了,我弄乙個吧 從今以...
字符集和字元編碼
字符集和字元編碼不錯的部落格 字符集 是乙個系統支援的所有抽象字元的集合。字元是各種文字和符號的總稱,包括各國家文字 標點符號 圖形符號 數字等。asicc,unicode,gbk,gb2312等 字元編碼 是一套法則,使用該法則能夠對自然語言的字元的乙個集合 如字母表或音節表 與其他東西的乙個集合...
字符集和字元編碼
字符集 建立文字檔案預設使用ansi,就是系統預設編碼方式,中文window系統預設使用gbk編碼方式 位元組 這是最基本的概念,位元組是計算儲存容量的一種計量單位,我們知道計算機只能識別1和0組成的二進位制位,乙個數就是1位 bit 為了方便計算,我們規定8位就是乙個位元組 字元 字元和位元組不太...