字元編碼

**字元編碼**（英語：Character encoding）、**字集碼**是把**字元集**中的字元編碼為指定集合中某一物件（例如：位元模式、自然數序列、8 位元組或者電脈衝），以便文字在電腦中儲存和通過通信網路的傳遞。常見的例子包括將拉丁字母表編碼成摩斯電碼和 ASCII。其中，ASCII 將字母、數字和其它符號編號，並用 7 位元的二進位來表示這個整數。通常會額外使用一個擴充的位元，以便於以 1 個位元組的方式儲存。

在電腦技術發展的早期，如 ASCII（1963 年）和 EBCDIC（1964 年）這樣的**字元集**逐漸成為標準。但這些字元集的局限很快就變得明顯，於是人們開發了許多方法來擴充它們。對於支援包括東亞 CJK 字元家族在內的寫作系統的要求能支援更大量的字元，並且需要一種系統而不是臨時的方法實現這些字元的編碼。

## 簡單字元集

按照慣例，人們認為字元集和字元編碼是同義詞，因為使用同樣的標準來定義提供什麼字元並且這些字元如何編碼到一系列的代碼單元（通常一個字元一個單元）。由於歷史的原因，MIME 和使用這種編碼的系統使用術語**字元集**來表示用於將一組字元編碼成一系列八位位元組資料的整個系統。

## 現代編碼模型

由統一碼和通用字元集所構成的現代字元編碼模型則沒有跟從簡單字元集的觀點。它們將字元編碼的概念分為：有哪些字元、它們的編號、這些編號如何編碼成一系列的「碼元」（有限大小的數字）以及最後這些單元如何組成八位位元組流。區分這些概念的核心思想是建立一個能夠用不同方法來編碼的一個通用字元集。為了正確地表示這個模型需要更多比「字元集」和「字元編碼」更為精確的術語表示。在 Unicode Technical Report (UTR) #17 中，現代編碼模型分為 5 個層次，所用的術語列在下面：

1. **抽象字元表**（Abstract character repertoire）是一個系統支援的所有抽象字元的集合。字元表可以是封閉的，即除非建立一個新的標準（ASCII 和多數 ISO/IEC 8859 系列都是這樣的例子），否則不允許添加新的符號；字元表也可以是開放的，即允許添加新的符號（統一碼和一定程度上代碼頁是這方面的例子）。特定字元表中的字元反映了如何將書寫系統分解成線性資訊單元的決定。例如拉丁、希臘和斯拉夫字母表分為字母、數字、變音符號、標點和如空格這樣的一些少數特殊字元，它們都能按照一種簡單的線性序列排列（儘管對它們的處理需要另外的規則，如帶有變音符號的字母這樣的特定序列如何解釋 —— 但這不屬於字元表的範疇）。為了方便起見，這樣的字元表可以包括預先編號的字母和變音符號的組合。其它的書寫系統，如阿拉伯語和希伯萊語，由於要適應雙向文字和在不同情形下按照不同方式交叉在一起的字形，就使用更為複雜的符號表表示。
2. **編碼字元集**（CCS:Coded Character Set）是將字元集 $C$ 中每個字元對映到 1 個坐標（整數值對：x, y）或者表示為 1 個非負整數 $N$ 。字元集及碼位對映稱為編碼字元集。例如，在一個給定的字元表中，表示大寫拉丁字母「A」的字元被賦予整數 65、字元「B」是 66，如此繼續下去。多個編碼字元集可以表示同樣的字元表，例如 ISO-8859-1 和 IBM 的頁碼 037 和頁碼 500 含蓋同樣的字元表但是將字元對映為不同的整數。由此產生了**編碼空間**（encoding space）的概念：簡單說就是包含所有字元的表的維度。可以用一對整數來描述，例如：GB 2312 的漢字編碼空間是 94 x 94。可以用一個整數來描述，例如：ISO-8859-1 的編碼空間是 256。也可以用字元的儲存單元尺寸來描述，例如：ISO-8859-1 是一個 8 位元的編碼空間。編碼空間還可以用其子集來表述，如行、列、面（plane）等。編碼空間中的一個位置（position）稱為**碼位**（code point）。一個字元所占用的碼位稱為**碼位值**（code point value）。1 個編碼字元集就是把抽象字元對映為碼位值。
3. **字元編碼表**（CEF:Character Encoding Form），也稱為 "storage format"，是將編碼字元集的非負整數值（即抽象的碼位）轉換成有限位元長度的整型值（稱為**碼元** code units）的序列。這對於定長編碼來說是個到自身的對映（null mapping），但對於變長編碼來說，該對映比較複雜，把一些碼位對映到一個碼元，把另外一些碼位對映到由多個碼元組成的序列。例如，使用 16 位元長的儲存單元儲存數字資訊，系統每個單元只能夠直接表示從 0 到 65,535 的數值，但是如果使用多個 16 位元單元就能夠表示更大的整數。這就是 CEF 的作用，它可以把 Unicode 從 0 到 140 萬的碼空間範圍的每個碼位對映到單個或多個在 0 到 65,5356 範圍內的碼值。最簡單的字元編碼表就是單純地選擇足夠大的單位，以保證編碼字元集中的所有數值能夠直接編碼（一個碼位對應一個碼值）。這對於能夠用使用八位元組來表示的編碼字元集（如多數傳統的非 CJK 的字元集編碼）是合理的，對於能夠使用十六位元來表示的編碼字元集（如早期版本的 Unicode）來說也足夠合理。但是，隨著編碼字元集的大小增加（例如，現在的 Unicode 的字元集至少需要 21 位才能全部表示），這種直接表示法變得越來越沒有效率，並且很難讓現有電腦系統適應更大的碼值。因此，許多使用新近版本 Unicode 的系統，或者將 Unicode 碼位對應為可變長度的 8 位元位元組序列的 UTF-8，或者將碼位對應為可變長度的 16 位元序列的 UTF-16。
4. **字元編碼方案**（CES:Character Encoding Scheme），也稱作 "serialization format"。將定長的整型值（即碼元）對映到 8 位元位元組序列，以便編碼後的資料的檔案儲存或網路傳輸。在使用 Unicode 的場合，使用一個簡單的字元來指定位元組順序是大端序或者小端序（但對於 UTF-8 來說並不需要專門指明位元組序）。然而，有些複雜的字元編碼機制（如 ISO/IEC 2022）使用控制字元跳脫序列在幾種編碼字元集或者用於減小每個單元所用位元組數的壓縮機制（如 SCSU、BOCU 和 Punycode）之間切換。
5. **傳輸編碼語法**（transfer encoding syntax），用於處理上一層次的字元編碼方案提供的位元組序列。一般其功能包括兩種：一是把位元組序列的值對映到一套更受限制的值域內，以滿足傳輸環境的限制，例如 Email 傳輸時 Base64 或者 quoted-printable，都是把 8 位元的位元組編碼為 7 位長的資料；另一是壓縮位元組序列的值，如 LZW 或者行程長度編碼等無失真壓縮技術。

**高層機制**（higher level protocol）提供了額外資訊，用於選擇 Unicode 字元的特定變種，如 XML 屬性 xml:lang

**字元對映**（character map）在 Unicode 中保持了其傳統意義：從字元序列到編碼後的位元組序列的對映，包括了上述的 CCS, CEF, CES 層次。

## 字元集、頁碼，與字元對映

術語字元編碼（character encoding），字元對映（character map），字元集（character set）或者頁碼，在歷史上往往是同義概念，即字元表（repertoire）中的字元如何編碼為碼元的流（stream of code units）–通常每個字元對應單個碼元。

碼元（Code Unit，也稱「代碼單元」）是指一個已編碼的文字中具有最短的位元組合的單元。對於 UTF-8 來說，碼元是 8 位元長；對於 UTF-16 來說，碼元是 16 位元長；對於 UTF-32 來說，碼元是 32 位元長。碼值（Code Value）是過時的用法。

頁碼通常意味著面向位元組的編碼，但強調是一套用於不能語言的編碼方案的集合。著名的如 "Windows" 頁碼系列，"IBM"/"DOS" 頁碼系列.

IBM 的字元資料表示體系（Character Data Representation Architecture - CDRA）與編碼字元集識別碼（coded character set identifiers - CCSIDs） 常常把 charset, character set, code page, or CHARMAP 等類似意義的術語混用.

Unix 或 Linux 不使用頁碼概念，它們用 charmap，比 locales 具有更廣泛的含義.

與上文的編碼字元集（Coded Character Set - CCS）不同，字元編碼（character encoding）是從抽象字元到代碼字（code word）的對映. HTTP（與 MIME）的用法中，字元集（character set）與字元編碼同義，但與 CCS 不是一個意思.

## 字元編碼（不全）

* ASCII
* EBCDIC

### 西歐標準

* ISO-8859-1
* ISO-8859-5
* ISO-8859-6
* ISO-8859-7
* ISO-8859-11
* ISO-8859-15
* ISO/IEC 646

### DOS 字元集（又稱 IBM 頁碼）

* CP437
* CP737
* CP850
* CP852
* CP855
* CP857
* CP858
* CP860
* CP861
* CP863
* CP865
* CP866
* CP869

### Windows 字元集

* Windows-1250
* Windows-1251：用於西里爾字母表
* Windows-1252
* Windows-1253
* Windows-1254
* Windows-1255：用於希伯萊語
* Windows-1256：用於阿拉伯語
* Windows-1257
* Windows-1258：用於越南語

### 亞洲字元集

#### 臺灣

* 大五碼
* 中文資訊交換碼（CCCII）
* 中文標準交換碼（CNS 11643）
* EUC

#### 日本

* ISO/IEC 2022
* Shift JIS
* EUC

#### 中國大陸及港澳

* GB 2312
* EUC
* GBK（規定檔案為 GB13000）
* GB 18030
* 香港增補字符集

#### 朝鮮半島

* EUC
* KOI8-R
* KOI8-U
* KOI7
* MIK

#### 越南

* 越南資訊交換標準代碼

#### 印度

* 印度文字資訊交換碼

#### Unicode

* Unicode
* UTF-7
* UTF-8
* UTF-16
* UTF-32

## 字元轉換工具

由於有很多種字元編碼方法被使用，從一種字元編碼轉換到另一種，需要一些工具。

跨平台：

* 網頁瀏覽器–大多數現代的網頁瀏覽器都具有此功能。一般是在選單 "檢視"（View）/"字元編碼"（Character Encoding）
* iconv –程式與編程 API，用於字元編碼轉換
* convert\_encoding.py –基於 Python 的轉換工具.
* decodeh.py –用於啟發性猜測編碼方案的演算法與模組.
* International Components for Unicode –一套 C 語言與 Java 語言的開源庫，由 IBM 提供，用於 Unicode 等多語言編碼的轉換、實現.
* chardet – Mozilla 的編碼自動檢測代碼的 Python 語言實現.
* 新版本的 Unix 命令 File 做字元編碼的檢測.（cygwin 與 mac 都有此命令）

Linux:

* recode –
* utrac – 將整個檔案內容從一種字元編碼轉換到另外一種
* cstocs –
* convmv –轉換檔名.
* enca –分析編碼模式.

Microsoft Windows:

* Encoding.Convert – .NET API
* MultiByteToWideChar/WideCharToMultiByte – Windows API
* cscvt –轉換工具
* enca –分析編碼方法

## 參考文獻

## 參閱

## 外部連結