【转】刨根究底字符编码之七——ANSI编码与代码页
一、ANSI編碼
1.
如前所述,在全世界所有國家和地區(qū)的文字符號統(tǒng)一編碼的UCS/Unicode編碼方案問世之前(UCS、Unicode后文有詳細介紹),各個國家、地區(qū)為了用計算機記錄并顯示自己的字符,都在ASCII編碼方案的基礎(chǔ)上,設(shè)計了各自的編碼方案。
比如歐洲先后設(shè)計了EASCII和ISO/IEC 8859系列字符編碼方案;為了顯示中文及相關(guān)字符,中國設(shè)計了GB系列編碼(“GB”為“國標(biāo)”的漢語拼音首字母縮寫,即“國家標(biāo)準(zhǔn)”之意)。
同樣,日文、韓文以及其他世界各個國家和地區(qū)的文字都有它們各自的編碼。所有這些各個國家和地區(qū)所獨立制定的既兼容ASCII又互相之間不兼容的字符編碼(準(zhǔn)確地來說應(yīng)該是既兼容ASCII又互相之間不完全兼容,因為這里所說的“不兼容”實際上指的是從整體中除開兼容ASCII之外的部分,下同,不再贅述),微軟統(tǒng)稱為ANSI編碼。
所以,即使知道是ANSI編碼,還需要知道這是哪一個國家或地區(qū)的才能解碼;而且,同一份文本,只能采用一種ANSI編碼方案來編碼,比如,無法用同一種ANSI編碼來表示既有漢字、又有韓文的文本。
2.
嚴格來說,ANSI的字面意思并非字符編碼,而是美國的一個非營利組織——美國國家標(biāo)準(zhǔn)學(xué)會(American National Standards Institute)的縮寫。ANSI這個組織做了很多標(biāo)準(zhǔn)制定工作,包括C語言規(guī)范ANSI C,還有與各國和地區(qū)既兼容ASCII又互相不兼容的字符編碼相對應(yīng)的“代碼頁(Code Page)”標(biāo)準(zhǔn)。(具體什么是代碼頁,以及代碼頁與ANSI編碼之間的關(guān)系,詳見下文第二節(jié)的介紹)
比如ANSI規(guī)定簡體中文GB編碼的代碼頁是936,所以GB編碼又叫做ANSI Code Page 936(ANSI標(biāo)準(zhǔn)的代碼頁936)。
各國和地區(qū)既兼容ASCII又互相不兼容的字符編碼之所以被微軟 統(tǒng)稱為ANSI編碼的原因即在于此。
后來,或許是出于沿用統(tǒng)一的稱呼之目的,有些在當(dāng)時還并未被ANSI定為標(biāo)準(zhǔn)的代碼頁,也被微軟稱之為ANSI代碼頁,比如CP943代碼頁。
在Windows系統(tǒng)的編碼處理中,ANSI編碼一般代表系統(tǒng)默認的編碼方式,而且并不是確定的某一種編碼方式——在簡體中文操作系統(tǒng)中ANSI編碼默認指的是GB系列編碼(GB2312、GBK、GB18030);在繁體中文操作系統(tǒng)中ANSI編碼默認指的是Big5編碼(港澳臺地區(qū)使用的繁體漢字編碼);在日文操作系統(tǒng)中ANSI編碼默認指的是Shift JIS編碼,等等。可在系統(tǒng)區(qū)域設(shè)置的系統(tǒng)Locale中查看、更改。(本文后面有詳細介紹)
(笨笨阿林原創(chuàng)文章,轉(zhuǎn)載請注明出處)
二、代碼頁(Code Page)
注:有關(guān)代碼頁的內(nèi)容,網(wǎng)上資料較少,因此下面有關(guān)代碼頁的內(nèi)容無法通過對多方資料來源的比對甄別以去蕪存菁,錯漏可能在所難免,還望多多指正。
1.
代碼頁的英文為Code Page,往往簡稱為CP。代碼頁也稱為“內(nèi)碼表”,是計算機中與特定字符集(準(zhǔn)確地說是字符集的某個字符編碼方式CEF)相對應(yīng)的一張字符編碼對照表(這里的字符編碼實際上指的是字符編碼模式CES,因此實際為“字符-字節(jié)”或“字符-字節(jié)序列”對照表,詳見后文)。
最初,IBM用代碼頁來稱呼其計算機BIOS所支持的字符編碼。當(dāng)時通用的操作系統(tǒng)都是命令行界面的,這些操作系統(tǒng)直接使用BIOS提供的字符繪制功能來顯示字符(或者是一組嵌入在顯卡字符生成器中的字形)。這些BIOS代碼頁也被稱為OEM代碼頁。
隨著圖形用戶界面操作系統(tǒng)的廣泛使用(最初被廣為接受的圖形用戶界面操作系統(tǒng)是Windows 3.1),操作系統(tǒng)本身具有了字符繪制的功能。微軟于是在Windows操作系統(tǒng)還沒有轉(zhuǎn)向UTF-16(UTF-16的推出要早于現(xiàn)在被廣為認可的UTF-8)作為編碼實現(xiàn)之前(即Windows2000發(fā)布之前),基于ANSI代碼頁標(biāo)準(zhǔn)定義了一系列支持ANSI編碼的代碼頁,因而被稱作“ANSI代碼頁”。代表性的是實現(xiàn)了ISO 8859-1(即Latin-1)的代碼頁1252(即CP1252),以及實現(xiàn)了GBK的代碼頁936(即CP936)。
現(xiàn)代操作系統(tǒng)中不同的語言和區(qū)域設(shè)置可能使用不同的代碼頁。
2.
除了上面提到的較為常見的ANSI代碼頁(即微軟所采用的代碼頁標(biāo)準(zhǔn)),以及IBM代碼頁,其他有些商業(yè)巨頭也制定有自己的代碼頁,比如Oracle代碼頁、SAP代碼頁,還有由多家公司聯(lián)合制定的代碼頁,比如EUC代碼頁(EUC為Extended Unix Code的縮寫,是由多家Unix系統(tǒng)開發(fā)公司針對Unix系統(tǒng)而聯(lián)合制定的代碼頁,使用8位編碼(即采用8位單字節(jié)碼元)來表示字符,于1991年標(biāo)準(zhǔn)化。EUC現(xiàn)在主要用于Unix、Mac及Linux等類Unix系統(tǒng)中表示及儲存漢語、日語及朝鮮語文字)。
后來代碼頁進一步擴展,除了原先針對ANSI編碼所定義的ANSI代碼頁,針對Unicode字符集的各UTF編碼方式(UTF-8、UTF-16、UTF-32等),各個組織和廠商往往也定義了相應(yīng)的代碼頁。
另外,不同的組織或廠商,對于同一種編碼方式往往使用各自不同的代碼頁名稱(一般都以數(shù)字來進行命名區(qū)分)。例如,UTF-8在IBM稱作代碼頁1208(即CP1208),在微軟稱作代碼頁65001(即CP65001),在SAP稱作代碼頁4110(即CP4110);Windows使用936代碼頁(CP936)、Mac系統(tǒng)使用EUC-CN代碼頁來表示GBK編碼(EUC-CN在類Unix系統(tǒng)中相當(dāng)于GBK編碼方案的別名,等同于Windows下的CP936代碼頁)。
(附:微軟公司定義的代碼頁一覽表:Code Page Identifiers - Windows applications)
3.
需要注意的是,在實踐中,代碼頁一般與其所直接對應(yīng)的字符集之間并非完全等同,往往因為種種原因(比如標(biāo)準(zhǔn)跟不上現(xiàn)實實踐的需要)而會對字符集有所擴展。
例如,微軟所采用的對應(yīng)于ISO 8859-1字符集(即Latin-1字符集)的ANSI代碼頁1252(即CP1252),就對Latin-1字符集有所擴展,其中編碼128~159也被定義了字符,這是與Latin-1字符集不同之處,用于表示英語和大多數(shù)歐洲語言(西班牙語和各種日耳曼/斯堪的納維亞語)。另外,IBM所采用的對應(yīng)于Shift JIS日文字符集的OEM代碼頁932(即CP932),也對Shift JIS有所擴展;而對應(yīng)于Shift JIS字符集的微軟ANSI代碼頁943(即CP943),也同樣對Shift JIS有所擴展。
4.
代碼頁可以體現(xiàn)為從字符映射到單字節(jié)值或多字節(jié)值的一張表格。
注意,針對ANSI編碼而言,雖然其屬于傳統(tǒng)字符編碼模型,但從現(xiàn)代字符編碼模型的角度來看,這里所提到的單字節(jié)值與多字節(jié)值指的是特定于系統(tǒng)平臺的物理意義上的字節(jié)序列,不是指與系統(tǒng)平臺無關(guān)的邏輯意義上的碼元序列(雖然對屬于傳統(tǒng)字符編碼模型的早期字符編碼方案而言,字符的碼元序列與字節(jié)序列其實是一樣的)。
而針對屬于現(xiàn)代字符編碼模型的Unicode字符集的各UTF編碼方式而言,則更是同樣如此。比如針對UTF-16所定義的代碼頁,其存儲的是針對UTF-16這種字符編碼方式CEF的某種字符編碼模式CES(即大端序或小端序之一,大端序、小端序的概念后文有詳細介紹)。
正因為這樣,代碼頁也被稱之內(nèi)碼表。
也就是說,代碼頁是字符集在計算機中的具體編碼實現(xiàn);特別是從現(xiàn)代字符編碼模型的角度而言,代碼頁可認為是字符集的某種字符編碼方式CEF的具體字符編碼模式CES在計算機中的具體實現(xiàn),可以將其理解為一張“字符-字節(jié)”(或更準(zhǔn)確地理解為“字符-字節(jié)序列”)映射表,計算機通過查表實現(xiàn)“字符-字節(jié)”之間的雙向“翻譯”。
代碼頁主要用于具體實現(xiàn)各編碼方案中的字符在計算機系統(tǒng)中的物理存儲和顯示。當(dāng)計算機讀取了一個二進制字節(jié),那這個字節(jié)到底屬于哪個字符,就需要到存儲在計算機中的某個代碼頁中查找,這個查找的過程就被稱為查表。
比如,當(dāng)使用輸入碼(即外碼)輸入漢字時,輸入法軟件需要將輸入碼(出現(xiàn)重碼時另加選擇編號)根據(jù)代碼頁轉(zhuǎn)換為機內(nèi)碼(即查表)進行存儲,以及再根據(jù)機內(nèi)碼和相應(yīng)的字體設(shè)定到對應(yīng)的字體文件中查找字形碼進行顯示。
5.
在Windows中,代碼頁是系統(tǒng)默認設(shè)置的(即默認系統(tǒng)區(qū)域設(shè)置),也可在(Windows7的)“控制面板-區(qū)域和語言-管理-非Unicode程序的語言-更改系統(tǒng)區(qū)域設(shè)置”中選擇列表中的語言進行更改。
注意,系統(tǒng)區(qū)域設(shè)置System Locale可用于確定在不使用Unicode編碼的程序(即非Unicode程序)中輸入和顯示字符的默認編碼方案(顯然主要是指ANSI編碼方案)和字體,這樣就可以讓非Unicode程序在計算機上使用指定的語言(實質(zhì)上是使用指定的ANSI編碼)得以正常運行。
因此,在計算機上安裝某些非Unicode程序時,如果出現(xiàn)亂碼,則可能需要更改默認的系統(tǒng)區(qū)域設(shè)置。為系統(tǒng)區(qū)域設(shè)置選擇不同的語言并不會影響Windows系統(tǒng)本身或其他使用Unicode編碼方案的程序(即Unicode程序)的語言顯示。
但是,很顯然,如果同一個操作系統(tǒng)中,多個非Unicode程序采用了各不相同的ANSI編碼,則同一時間只有一種ANSI編碼的非Unicode程序的語言顯示是正常的,采用其他ANSI編碼的非Unicode程序的語言顯示為亂碼;而同一個非Unicode程序是無法采用不同的ANSI編碼的,比如同時采用中文和韓文,在非Unicode程序中是無法實現(xiàn)的,因為同一時間必定有其中之一是亂碼的。
不過,現(xiàn)在Unicode編碼方案已經(jīng)成為了主流,非Unicode程序已經(jīng)難得一見了。
(笨笨阿林原創(chuàng)文章,轉(zhuǎn)載請注明出處)
三、微軟Windows操作系統(tǒng)中ANSI代碼頁的設(shè)置
1.
微軟為了適應(yīng)世界上不同地區(qū)用戶的文化背景和生活習(xí)慣,在Windows中設(shè)計了區(qū)域(Locale)設(shè)置的功能。
Locale是指特定于某個國家或地區(qū)的一組設(shè)定,包括代碼頁,以及數(shù)字、貨幣、時間和日期的格式等。
在Windows內(nèi)部,其實有兩個Locale設(shè)置:系統(tǒng)Locale和用戶Locale。系統(tǒng)Locale決定代碼頁,用戶Locale決定數(shù)字、貨幣、時間和日期的格式等。
可以在Windows控制面板的“區(qū)域和語言選項”中設(shè)置系統(tǒng)Locale(非Unicode程序的語言)和用戶Locale(標(biāo)準(zhǔn)和格式)。如下圖所示:
?
(Windows XP中的Locale設(shè)置)
(Windows 7中的Locale設(shè)置)
2.
系統(tǒng)Locale對應(yīng)的代碼頁被作為Windows系統(tǒng)的默認代碼頁。在沒有明確指定某個文本所采用的編碼方案時,Windows系統(tǒng)將按照系統(tǒng)Locale中所指定的默認代碼頁(實質(zhì)上代表了某個編碼方案)來解釋該文本數(shù)據(jù)。這個默認代碼頁通常被稱作ANSI代碼頁(簡稱ACP;注意,如前所述,雖然非ANSI編碼的Unicode各UTF編碼也同樣定義了代碼頁,但系統(tǒng)Locale中所設(shè)定的默認代碼頁之所以通常被稱為ACP,是因為系統(tǒng)Locale主要是針對非Unicode程序而設(shè)置的)。
在Windows XP的“區(qū)域和語言選項”高級頁面的“代碼頁轉(zhuǎn)換表”中,可看到各種語言(實質(zhì)上是各個編碼方案)的代碼頁(但Windows7中已經(jīng)不能直接看到了)。例如:
·874 (ANSI/OEM -泰文)
·932 (ANSI/OEM -日文Shift-JIS)
·936 (ANSI/OEM -簡體中文GBK)
·949 (ANSI/OEM -韓文)
·950 (ANSI/OEM -繁體中文Big5)
·1250 (ANSI -中歐)
·1251 (ANSI -西里爾文)
·1252 (ANSI -拉丁文)
·1253 (ANSI -希臘文)
·1254 (ANSI -土耳其文)
·1255 (ANSI -希伯來文)
·1256 (ANSI -阿拉伯文)
·1257 (ANSI -波羅的海文)
·1258 (ANSI/OEM -越南)
(笨笨阿林原創(chuàng)文章,轉(zhuǎn)載請注明出處)
?
【預(yù)告:下一篇將開始正式講解Unicode編碼方案,敬請關(guān)注!】
總結(jié)
以上是生活随笔為你收集整理的【转】刨根究底字符编码之七——ANSI编码与代码页的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 00后女生手写奶茶换算公式 60天不喝能
- 下一篇: Sharepoint 修改密码