字符編碼

字符編碼（Character encoding）、字碼、字集碼是把字符集中的字符為指定集合中某一對象（例如：位元模式、自然數序列、八位元或者電脈衝），以便文本在電腦中存儲和通過通信網路的傳遞。

純就字面解釋，這些術語是有不同的概念，但在許多的中文語境，這些術語會混用，有相同的概念。字符集，是指「字符的集合」，如中文字符集、英文字符集，不牽涉到編碼。字符編碼、字集碼、字碼，則是「對於某個字符集，為其字符編碼」，根據語義，有時指單一字符的編碼，有時是指全部字符的編碼。

在電腦支援語言、文字的過程中，要支援某個文字，必然要搜集所使用的字符，為其編碼，因此，初期並未區分字符集和字符編碼的不同。譬如，大五碼、國標碼、ASCII既指字符集，又指針對此字符集的編碼方式。在統一碼之後，則細分字符集和編碼形式的不同。同一個字符集，可以有不同的編碼形式，如UTF-8、UTF-16。

常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII。其中，ASCII將字母、數字和其它符號編號，並用7位元的二進位來表示這個整數。通常會額外使用一個擴充的位元，以便於以1個字節的方式存儲。

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

有時，為強調其所使用的方式而使用其他術語，譬如：為說明「電腦系統『內部』

處理文字資料所使用的字符編碼」時，會使用內碼。為「不同電腦系統之間，為了『交換』資料所採用的字符編碼」時，會使用交換碼。

## 簡單字符集

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

## 現代編碼模型

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

- 抽象字符表（Abstract character repertoire）是一個系統支持的所有抽象字符的集合。字符表可以是封閉的，即除非創建一個新的標準（ASCII和多數ISO/IEC 8859系列都是這樣的例子），否則不允許添加新的符號；字符表也可以是開放的，即允許添加新的符號（統一碼和一定程度上代碼頁是這方面的例子）。特定字符表中的字符反映了如何將書寫系統分解成線性資訊單元的決定。例如拉丁、希臘和斯拉夫字母表分為字母、數字、變音符號、標點和如空格這樣的一些少數特殊字符，它們都能按照一種簡單的線性序列排列（儘管對它們的處理需要另外的規則，如帶有變音符號的字母這樣的特定序列如何解釋——但這不屬於字符表的範疇）。為了方便起見，這樣的字符表可以包括預先編號的字母和變音符號的組合。其它的書寫系統，如阿拉伯語和希伯萊語，由於要適應雙向文字和在不同情形下按照不同方式交叉在一起的字形，就使用更為複雜的符號表表示。
- 編碼字符集（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個編碼字符集就是把抽象字符映射為碼位值。
- 字符編碼表（CEF:Character Encoding Form），也稱為"storage format"，是將編碼字符集的非負整數值（即抽象的碼位）轉換成有限比特長度的整型值（稱為碼元code units）的序列。這對於定長編碼來說是個到自身的映射（null mapping），但對於變長編碼來說，該映射比較複雜，把一些碼位映射到一個碼元，把另外一些碼位映射到由多個碼元組成的序列。例如，使用16比特長的存儲單元保存數字資訊，系統每個單元只能夠直接表示從0到65,535的數值，但是如果使用多個16位單元就能夠表示更大的整數。這就是CEF的作用，它可以把Unicode從0到140萬的碼空間範圍的每個碼位映射到單個或多個在0到65,535範圍內的碼值。最簡單的字符編碼表就是單純地選擇足夠大的單位，以保證編碼字符集中的所有數值能夠直接編碼（一個碼位對應一個碼值）。這對於能夠用使用八位元組來表示的編碼字符集（如多數傳統的非CJK的字符集編碼）是合理的，對於能夠使用十六位元來表示的編碼字符集（如早期版本的Unicode）來說也足夠合理。但是，隨著編碼字符集的大小增加（例如，現在的Unicode的字符集至少需要21位才能全部表示），這種直接表示法變得越來越沒有效率，並且很難讓現有電腦系統適應更大的碼值。因此，許多使用新近版本Unicode的系統，或者將Unicode碼位對應為可變長度的8位字節序列的UTF-8，或者將碼位對應為可變長度的16位序列的UTF-16。
- 字符編碼方案（CES:Character Encoding Scheme），也稱作"serialization format"。將定長的整型值（即碼元）映射到8位字節序列，以便編碼後的數據的文件存儲或網路傳輸。在使用Unicode的場合，使用一個簡單的字符來指定字節順序是大端序或者小端序（但對於UTF-8來說並不需要專門指明字節序）。然而，有些複雜的字符編碼機制（如ISO/IEC 2022）使用控制字符轉義序列在幾種編碼字符集或者用於減小每個單元所用字節數的壓縮機制（如SCSU、BOCU和Punycode）之間切換。
- 傳輸編碼語法（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：用於越南語

### 亞洲字符集

尤其是漢字編碼。

#### 臺灣

- 大五碼
- 中文資訊交換碼
- 中文標準交換碼
- EUC

#### 中國大陸及港澳

- GB/T 2312
- GB/T 12345
- EUC
- GBK（規定文件為GB13000）
- GB 18030
- 香港增補字符集

#### 日本

- ISO/IEC 2022
- Shift JIS
- EUC

#### 朝鮮半島

- EUC
- KOI8-R
- KOI8-U
- KOI7
- MIK Code page

#### 越南

- 越南資訊交換標準代碼

#### 印度

- 印度文字資訊交換碼

#### 統一碼

- 統一碼
- UTF-7
- UTF-8
- UTF-16
- UTF-32

## 字符轉換工具

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

跨平台：

- 網頁瀏覽器–大多數現代的網頁瀏覽器都具有此功能。一般是在菜單"查看"（View）/"字符編碼"（Character Encoding）
- iconv –程序與編程API，用於字符編碼轉換
- convert_encoding.py –基於Python的轉換工具.
- decodeh.py –用於啟發性猜測編碼方案的演算法與模塊.
- 國際統一碼部件 –一套C語言與Java語言的開源庫，由IBM提供，用於統一碼等多語言編碼的轉換、實現.
- 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 –分析編碼方法

## 外部連結

- Character sets registered by Internet Assigned Numbers Authority
- Unicode Technical Report #17: Character Encoding Model
- SIL's freeware fonts, editors and documentation See SIL
- ICU Converter Explorer
- The Cyrillic Charset soup
- Early history of character set standardization
- Character Sets And Code Pages At The Push Of A Button
- A complete introduction to Japanese character encodings
- A tutorial on character code issues
- Online Char (ASCII), HEX, Binary, Base64, etc... Encoder/Decoder with MD2, MD4, MD5, SHA1+2, etc. hashing algorithms
- Universal Cyrillic decoder ,一個用來幫助恢復由於錯誤字符編碼產生的不可讀的西里爾字母的在線程序（以及其它的一些程序）.
- Introduction to i18n，請參閱Chapter 3 - Important Concepts for Character Coding Systems
- 漢字字符編碼查詢
- 精確解釋Unicode