字符集的基礎知識

2021-08-30 12:44:35 字數 4159 閱讀 3664

眾所周知,計算機是工作在二進位制基礎上的。也就是說從本質上講,計算機只認識數字,而不認識字元。因此,要計算機認識或表示字元就必須提供字元與數字的某種對映機制。這種對映就是通過所謂的字符集來完成的。

字符集是一組文字和圖形符號,每個符號對映到一組非負整數。與字符集密切相關的概念是字元編碼,字元編碼是指字符集對映到特定寬度的一些單元,並定義位元組序列化和排序的規則。

字符集的發展經歷了乙個從ascii到unicode(utf-8)的演變過程。ascii是美國資訊交換標準委員會(american standards committee for information interchange)的縮寫。我們知道,電子計算機技術是從美國開始發展起來的,因為美國使用的文字為美國英語,美國規定的計算機資訊交換用的字元編碼集是人們熟知的ascii碼,它以8bit位元組為單位儲存,ascii的0-31及127為控制符,32-126為可見字     符,包括所有的英文本母,阿拉伯數字和其他一些常見符號,128-255的ascii碼則沒有定義。比如,computer用ascii表示就是如下一些數字:67、111、109、112、117、116、101和114。由於ascii只用了7bit,而儲存時使用的是8bit,因此,位元組的最高為在計算機內部通常保持為0,在資料傳輸時,該位常用作奇偶校驗位。

ascii 由於其字元個數有限,常常難以滿足實際應用中的需要。因此,國際化標準組織又建立了所謂的ascii擴充套件字符集,這種字符集就是用ascii字元最高位為 1的單元來表示那些擴充套件字元,也就是用十進位制128-255來表示這些擴充套件字元。其中最常見的要數iso-8859-1字符集。值得一提的是,因為考慮到程式中處理的資訊大多是西文資訊,因此有些web容器(如tomcat)在處理所接收到的request字串時,如果您沒有指定request的編碼方式則系統就預設地採用iso-8859-1,明白這一點對理解本章後面的問題會有幫助。

相比西方的拼音文字,東方的文字(如像中文這樣的象形文本)的字元數要大得多,根本無法在乙個位元組內將它們表示出來,因此,它們以兩個位元組為單位儲存,以中文國標字符集gb2312為例,漢字區的內碼範圍是:高位元組b0-f7,低位元組a1-fe。可見,兩個位元組的最高位都為1。

系統可以據此判斷,若第乙個位元組大於127,則把與該位元組後緊接著的乙個位元組結合起來共兩個位元組組成乙個中文字元。這種由多個位元組儲存乙個字元的字符集叫多位元組字符集(multibyte charsets),對應的像ascii這種用乙個位元組儲存乙個字元的字符集叫單位元組字符集(singlebyte charsets)。在gb2312字符集中,ascii字元仍然用乙個位元組儲存,換句話說該ascii是該字符集的子集。

gb2312 共收錄了7445個字元,包括6763個漢字和682個其他符號。由於該字符集包含的漢字數太少,許多生僻一點的字都不包含在內,給實際應用帶來了不便。以後又對它進行了擴充套件,這就有了我們現在廣泛使用的gbk字符集,gbk是現階段windows及其他一些中文作業系統的預設字符集。它包含2萬多個字元,除了保持和gb2312相容外,還包含正體中文本,日文字元和韓文本元。值得注意的是gbk只是乙個規範而不是國家標準,新的國家標準是 gb18030-2000,它是比gbk包含字元更多的字符集。

我國的台灣地區使用的文字是繁體字,其字符集是big5,而日本採用的字符集則是sjis。它們的編碼方法與gb2312類似,它們的ascii字元部分是相容的,但擴充套件部分的編碼則是不相容的,比如這幾種字符集中都有「中文」這兩個字元,但他們在各自的字符集中的編碼並不相同,這就是用gb2312寫成的網頁用big5瀏覽時,看到的是亂糟糟的資訊的原因。

可見,在字符集的世界裡,呈現給我們的是乙個群雄割據的局面,各字符集擁有一塊自己的地盤。這給各國和各地區交換資訊帶來了很大的困難。比如,在早期的程式設計實踐中,如何識別中文字元和擴充套件ascii字元,如何統計字元數等看似簡單的問題,處理起來是那樣的棘手,再加上各種應用軟體採用的處理方式也各不相同。在程式設計實踐中,那種夢魘般的感覺可能會讓很多處理過這類問題的老一些的程式設計師至今都揮之不去。同時,這些問題也給國際化(本地化)程式設計造成了很大的麻煩。

常言道:「分久必合」,如果說以前各應用程式採用的各自的一些技巧來處理字符集問題是揚湯止沸的話,那麼,隨著國際標準iso10646定義的通用字符集(universal character set即ucs)的出現則起到了釜底抽薪的作用,因為該字符集的出現使這種局面發生了徹底的改觀。ucs 是所有其他字符集標準的乙個超集。它保證與其他字符集是雙向相容的。就是說,如果你將任何文字字串翻譯到ucs格式,然後再翻譯回原編碼,你不會丟失任何資訊。ucs包含了用於表達所有已知語言的字元。

iso 10646定義了乙個31位的字符集。然而,在這巨大的編碼空間中,迄今為止只分配了前65534個碼位(0x0000到0xfffd)。這個ucs的16位子集稱為基本多語言面(basic multilingual plane,bmp)。被編碼在16位bmp以外的字元都屬於非常特殊的字元(比如象形文本),且只有專家在歷史和科學領域裡才會用到它們。

ucs 不僅給每個字元分配乙個**,而且賦予了乙個正式的名字。表示乙個ucs值的十六進製制數,通常在前面加上「u+」,就像u+0041代表字元「拉丁大寫字母a」。ucs字元u+0000到u+007f與us-ascii(iso 646)是一致的,u+0000到u+00ff與iso 8859-1(latin-1)也是一致的。這裡要注意的是它是以16bit為單位儲存的,即便對字母「a」也是用16bit,這是與前面介紹的所有字符集不同的地方。

歷史上,在國際標準化組織研究iso10646標準的同時,另乙個由多語言軟體製造商組成的協會也在從事創立單一字符集的工作,這就是現在人們熟知的unicode。後面,我們將視iso10646和unicode為同乙個東西。

有了unicode,似乎字符集問題有了乙個近乎完美的解決方案(唯一明顯的缺憾是原來的單位元組字元要用兩個位元組來儲存,要多用一些儲存空間),但不要高興得過早。由於歷史的原因,一些作業系統,如unix、linux等都是基於ascii設計的。此外,還有一些資料庫管理系統軟體,如oracle等也是圍繞ascii來設計的(從oracle 8i的***上介紹的設定系統字符集和字段的字符集中可以間接地看出這一點)。在這些系統中直接用unicode會導致嚴重的問題。用這些編碼的字串會包含一些特殊的字元,比如 '\0' 或 '/',它們在檔名和其他c庫函式引數裡都有特別的含義。另外,大多數使用ascii檔案的unix下的工具,如果不進行重大修改是無法讀取16位的字元的。基於這些原因,在檔名、文字檔案以及環境變數等地方直接使用unicode是不合適的。

為了讓unicode字符集的應用落到實處,在iso10646-1 annex r和rfc 2279裡定義的 utf-8(unicode transformation form 8-bit form)編碼沒有這些問題。

ucs字元u+0000到u+007f(ascii)被編碼為位元組0x00到0x7f(保證了與ascii相容)。這意味著只包含7位ascii字元的檔案在ascii和utf-8兩種編碼方式下是一樣的。

所有大於u+007f的ucs字元被編碼為乙個多位元組的串,每個位元組都有標記位集。因此,ascii位元組(0x00-0x7f)不可能作為任何其他字元的一部分。

表示非ascii字元的多位元組串的第乙個位元組總是在0xc0到0xfd的範圍內,並指出這個字元包含多少個位元組(這可以從**13.1中非常直觀地看出,該位元組由n個1帶乙個0的形式組成,n代表該字元要用的位元組數)。多位元組串的其餘位元組都在0x80到0xbf範圍內。這使得重新同步非常容易,並使編碼無國界,且很少受丟失位元組的影響。

utf-8編碼字元理論上可以最多到6個位元組長,然而16位bmp字元最多只用到3位元組長。

位元組0xfe和0xff在utf-8編碼中從未用到。

unicode到utf-8的轉換如下表所示:

**13.1

unicode

utf-8

00000000-0000007f

0******x

00000080-000007ff

110***xx 10******

00000800-0000ffff

1110***x 10****** 10******

00010000-001fffff

11110*** 10****** 10****** 10******

00200000-03ffffff

111110xx 10****** 10****** 10****** 10******

04000000-7fffffff

1111110x 10****** 10****** 10****** 10****** 10******

通過utf-8這種形式,unicode終於可以廣泛的在各種情況下使用了。在討論jsf的國際化程式設計之前,我們先來看看我們以前在jsp程式設計中是怎樣處理中文問題的,以及我們經常遇到的中文亂碼是怎樣造成的。

Oracle基礎知識 遠端連線 字符集設定

quote 設定pl sql字符集 sqlplus nolog 遠端連線 conn 使用者名稱 密碼 主機 本地連線 conn 使用者名稱 密碼 as sysdba 2.查詢當前資料庫的字符集格式 select userenv language from dual 結果集 simplified ch...

中文字符集編碼的基礎知識

字元是各種文字和符號的總稱,包括各國家文字 標點符號 圖形符號 數字等。字符集是多個字元的集合,字符集種類較多,每個字符集包含的字元個數不同,常見字符集名稱 ascii字符集 gb2312字符集 big5字符集 gb 18030字符集 unicode字符集等。計算機要準確的處理各種字符集文字,需要進...

中文字符集與字元編碼的基礎知識

字元是各種文字和符號的總稱,包括各國家文字 標點符號 圖形符號 數字等。字符集是多個字元的集合,字符集種類較多,每個字符集包含的字元個數不同,常見字符集名稱 ascii字符集 gb2312字符集 big5字符集 gb 18030字符集 unicode字符集等。計算機要準確的處理各種字符集文字,需要進...