字符編碼簡單介紹
1. ASCII碼
ASCII (American Standard Code for Information Interchange, 美國標準信息交換代碼),是基於拉丁字母的一套編碼系統。主要用於顯示現代英語和其它西歐語言。它是現今最通用的單字節編碼系統。
單個字節能夠表示256個不同的字符,只是 ASCII 僅僅使用了當中低於\x80
(即最高位字節為0)的一半來表示全部的英文字符以及一些控制字符,因此 ASCII 碼的實際取值範圍為0x00
到0x7f
之間,一共128個字符。
2. 多字節字符集MBCS
ASCII字符集中僅僅含有英文字符,不能滿足其它語言的需求。於是非常多語言就制定了一套自己的編碼。由於 ASCII 是單字節的,能表示的字符數量太少,因此這些編碼非常多都使用多個字節來表示單個字符。比如 GBK 等。 這些編碼的規則都比較類似: 假設第一個字節是\x80
下面。則仍然表示 ASCII 字符,而假設是\x80
以上,則跟下一個字節一起(共兩個字節)表示一個字符。
IBM發明了一個叫Code Page
的概念,將這些編碼都收入囊中並分配頁碼,GBK 是第936頁,也就是CP936
。所以,也能夠使用CP936
表示 GBK 。
這些各種語言自己制定的編碼統稱 MBCS (Multi-Byte Character Set)。眼下都是用了雙字節,所以有時候也稱為 DBCS
必須明白的是,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-8 中 ASCII 字符仍然使用相同的一個字節表示。這使得原來處理 ASCII 字符的軟件無須或僅僅須做少部分改動,就可以繼續使用。因此,它逐漸成為電子郵件、網頁及其它存儲或發送文字的應用中。優先採用的編碼。
UTF-8 使用一至六個字節為每一個字符編碼(雖然如此。2003年11月 UTF-8 被RFC 3629
又一次規範,僅僅能使用原來 Unicode 定義的區域。U+0000
到U+10FFFF
。也就是說最多四個字節):
- 128個 US-ASCII 字符僅僅需一個字節編碼(Unicode 範圍由
U+0000
至U+007F
). - 帶有附加符號的拉丁文、希臘文、西裏爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則須要兩個字節編碼( Unicode 範圍由
U+0080
至U+07FF
)。 - 其它基本多文種平面( BMP) 中的字符(這包括了大部分經常使用字,如大部分的漢字)使用三個字節編碼(Unicode 範圍由
U+0800
至U+FFFF
)。 - 其它極少使用的 Unicode 輔助平面的字符使用四至六字節編碼(Unicode 範圍由
U+10000
至U+1FFFFF
使用四字節,Unicode 範圍由U+200000
至U+3FFFFFF
使用五字節,Unicode 範圍由U+4000000
至U+7FFFFFFF
使用六字節)。
對上述提及的第四種字符而言,UTF-8 使用四至六個字節來編碼似乎太耗費資源了。但 UTF-8 對全部經常使用的字符都能夠用三個字節表示,並且它的還有一種選擇。UTF-16 編碼,對前述的第四種字符相同須要四個字節來編碼。所以要決定 UTF-8 或 UTF-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 ,但即使沒有 BOM,Unicode 還是能夠讀取的,僅僅是像 MBCS 的編碼一樣。須要另行指定詳細的編碼。否則解碼可能會失敗。
絕大多數編輯器在沒有BOM時都是以 UTF-8 作為默認編碼讀取。
即使是保存時默認使用 ANSI (MBCS)的記事本。在讀取文件時也是先使用 UTF-8 測試編碼。假設能夠成功解碼。則使用 UTF-8 解碼。這個別扭的做法造成了一個BUG:假設你新建文本文件並輸入姹塧
然後使用 ANSI 保存。再打開就會變成 漢a
。
參考資料:
- ASCII wikipedia
- Unicode wikipedia
- UTF-8 wikipedia
- Python字符編碼詳細解釋
- 字符編碼簡單介紹
字符編碼簡單介紹