1. 程式人生 > >字符編碼簡單介紹

字符編碼簡單介紹

浪費 RM article java編程 lin code page wikipedia 科學 linu

1. ASCII碼

ASCII (American Standard Code for Information Interchange, 美國標準信息交換代碼),是基於拉丁字母的一套編碼系統。主要用於顯示現代英語和其它西歐語言。它是現今最通用的單字節編碼系統。
單個字節能夠表示256個不同的字符,只是 ASCII 僅僅使用了當中低於\x80(即最高位字節為0)的一半來表示全部的英文字符以及一些控制字符,因此 ASCII 碼的實際取值範圍為0x000x7f之間,一共128個字符。

2. 多字節字符集MBCS

ASCII字符集中僅僅含有英文字符,不能滿足其它語言的需求。於是非常多語言就制定了一套自己的編碼。由於 ASCII 是單字節的,能表示的字符數量太少,因此這些編碼非常多都使用多個字節來表示單個字符。比如 GBK 等。 這些編碼的規則都比較類似: 假設第一個字節是\x80下面。則仍然表示 ASCII 字符,而假設是\x80以上,則跟下一個字節一起(共兩個字節)表示一個字符。

IBM發明了一個叫Code Page的概念,將這些編碼都收入囊中並分配頁碼,GBK 是第936頁,也就是CP936。所以,也能夠使用CP936表示 GBK

這些各種語言自己制定的編碼統稱 MBCS (Multi-Byte Character Set)。眼下都是用了雙字節,所以有時候也稱為 DBCS

(Double-Byte Character Set)。

必須明白的是,MBCS 並非指某一種特定的編碼,Windows裏依據你設定的區域不同。MBCS 代表不同的編碼,而Linux裏無法使用 MBCS 作為編碼。

在Windows中你看不到 MBCS 這幾個字符。由於微軟使用了 ANSI 這個稱呼,記事本的另存為對話框裏編碼 ANSI 就是 MBCS

在中文簡體 Windows 默認的區域設定中。ANSI 代表 GBK 編碼。

3. Unicode

由於各種不同的 MBCS 編碼互相不兼容。使用、轉換起來非常不方便,於是便有了 Unicode

Unicode (萬國碼、國際碼、統一碼、單一碼)是計算機科學領域裏的一項業界標準。它對世界上大部分的文字系統進行了整理、編碼,使得電腦能夠用更為簡單的方式來呈現和處理文字。

Unicode 發展由非營利機構統一碼聯盟負責,該機構致力於讓Unicode方案替換既有的字符編碼方案。由於既有的方案往往空間非常有限,亦不適用於多語環境。

Unicode 備受認可,並廣泛地應用於電腦軟件的國際化與本地化過程。有非常多新科技,如可擴展置標語言、Java編程語言以及現代的操作系統,都採用 Unicode 編碼。

最初的Unicode標準UCS-2使用兩個字節表示一個字符,一共能表示 256×個字符。不久後又有人認為還是太少了,於是出現了用4個字節表示一個字符的UCS-4標準。

UCS (Unicode Character Set)僅僅是字符相應碼位的一張表而已。

詳細怎樣傳輸和儲存字符則是由 UTF (UCS Transformation Format)來指定。

一開始直接使用 UCS 的碼位來保存字符。這就是UTF-16,比方這個字的碼位是6C49,則直接使用\x6C\x49保存(UTF-16-BE,BE指Big Endian),或是倒過來使用\x49\x6C保存(UTF-16-LE,LE指Little Endian)。

可是這樣的保存方式在保存英文字符時,會浪費非常多存儲空間( ASCII 保存一個字符僅僅須要一個字節)。於是變有了 UTF-8

UTF-8 是一種變長並且兼容 ASCII 的字符編碼,在 UTF-8ASCII 字符仍然使用相同的一個字節表示。這使得原來處理 ASCII 字符的軟件無須或僅僅須做少部分改動,就可以繼續使用。因此,它逐漸成為電子郵件、網頁及其它存儲或發送文字的應用中。優先採用的編碼。

UTF-8 使用一至六個字節為每一個字符編碼(雖然如此。2003年11月 UTF-8RFC 3629又一次規範,僅僅能使用原來 Unicode 定義的區域。U+0000U+10FFFF。也就是說最多四個字節):

  • 128個 US-ASCII 字符僅僅需一個字節編碼(Unicode 範圍由U+0000U+007F).
  • 帶有附加符號的拉丁文、希臘文、西裏爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則須要兩個字節編碼( Unicode 範圍由U+0080U+07FF)。
  • 其它基本多文種平面( BMP) 中的字符(這包括了大部分經常使用字,如大部分的漢字)使用三個字節編碼(Unicode 範圍由U+0800U+FFFF)。
  • 其它極少使用的 Unicode 輔助平面的字符使用四至六字節編碼(Unicode 範圍由U+10000U+1FFFFF使用四字節,Unicode 範圍由U+200000U+3FFFFFF使用五字節,Unicode 範圍由U+4000000U+7FFFFFFF使用六字節)。

對上述提及的第四種字符而言,UTF-8 使用四至六個字節來編碼似乎太耗費資源了。但 UTF-8 對全部經常使用的字符都能夠用三個字節表示,並且它的還有一種選擇。UTF-16 編碼,對前述的第四種字符相同須要四個字節來編碼。所以要決定 UTF-8UTF-16 哪種編碼比較有效率。還要視所使用的字符的分布範圍而定。

另外值得一提的是 BOM (Byte Order Mark)。我們在儲存文件時,文件使用的編碼並沒有保存,打開時則須要我們記住原先保存時使用的編碼並使用這個編碼打開,這樣一來就產生了很多麻煩。UTF 則引入了 BOM 來表示自身編碼,假設一開始讀入的幾個字節是當中之中的一個,則代表接下來要讀取的文字使用的編碼是相應的編碼:

BOM BYTES
BOM_UTF8 \xef\xbb\xbf
BOM_UTF16_LE \xff\xfe
BOM_UTF16_BE \xfe\xff

並非全部的編輯器都會寫入 BOM ,但即使沒有 BOMUnicode 還是能夠讀取的,僅僅是像 MBCS 的編碼一樣。須要另行指定詳細的編碼。否則解碼可能會失敗。
絕大多數編輯器在沒有BOM時都是以 UTF-8 作為默認編碼讀取。

即使是保存時默認使用 ANSI (MBCS)的記事本。在讀取文件時也是先使用 UTF-8 測試編碼。假設能夠成功解碼。則使用 UTF-8 解碼。這個別扭的做法造成了一個BUG:假設你新建文本文件並輸入姹塧然後使用 ANSI 保存。再打開就會變成 漢a

參考資料:

  • ASCII wikipedia
  • Unicode wikipedia
  • UTF-8 wikipedia
  • Python字符編碼詳細解釋
  • 字符編碼簡單介紹

字符編碼簡單介紹