定義,編碼常識,簡介,編碼分類,體系,ASCII,國標,GBK,BIG5,HZ碼,CJK碼,ISO,編碼種類,文字編碼,語義編碼,電子編碼,PCM編碼,神經編碼,記憶編碼,加密,解碼,字元集編,
定義 在
計算機硬體 中,
編碼 (coding)是指用
代碼 來表示各組數據資料,使其成為可利用計算機進行處理和分析的信息。代碼是用來表示事物的記號,它可以用數字、字母、特殊的符號或它們之間的組合來表示
將
數據 轉換為代碼或編碼字元,並能譯為原數據形式。是計算機書寫指令的過程,
程式設計 中的一部分。在地圖自動製圖中,按一定規則用數字與字母表示地圖內容的過程,通過編碼,使計算機能識別地圖的各地理要素。
n位
二進制數 可以組合成2的n次方個不同的信息,給每個信息規定一個具體碼組,這種過程也叫編碼。
編碼常識 簡介 GB編碼標準中,比較常用的是GB2312和GBK兩種,GB2312是GBK的一個子集,GB2312編碼範圍是 0xA1A1 - 0xFEFE ,如果純粹的 GB2312編碼,處理起來是十分簡單的,但處理GBK字元集時有些小的提示,先說說GBK編碼的標準吧:
GBK 採用雙位元組表示,總體編碼範圍為 8140-FEFE,首位元組在 81-FE 之間,尾位元組在 40-FE 之間,剔除 xx7F 一條線。總計 23940 個碼位,共收入 21886 個漢字和圖形符號,其中漢字(包括部首和構件)21003 個,圖形符號 883 個。
編碼分類 1. 漢字區。包括:
a. GB 2312 漢字區。即 GBK/2: B0A1-F7FE。收錄 GB 2312 漢字 6763 個,按原順序排列。
b. GB 13000.1 擴充漢字區。包括:
(1) GBK/3: 8140-A0FE。收錄 GB 13000.1 中的 CJK 漢字 6080 個。
(2) GBK/4: AA40-FEA0。收錄 CJK 漢字和增補的漢字 8160 個。
CJK 漢字在前,按 UCS 代碼大小排列;增補的漢字(包括部首和構件)在後,按《
康熙字典 》的頁碼/字位排列。
2. 圖形符號區。包括:
a. GB 2312 非漢字元號區。即 GBK/1: A1A1-A9FE。其中除 GB 2312 的符號外,
還有 10 個小寫羅馬數字和 GB 12345 增補的符號。計符號 717 個。
b. GB 13000.1 擴充非漢字區。即 GBK/5: A840-A9A0。BIG-5 非漢字元號、結構符和“○”排列在此區。計符號 166 個。
3. 用戶自定義區:分為(1)(2)(3)三個小區。
(1) AAA1-AFFE,碼位 564 個。
(2) F8A1-FEFE,碼位 658 個。
(3) A140-A7A0,碼位 672 個。
第(3)區儘管對用戶開放,但限制使用,因為不排除未來在此區域增補新字元的可能性。
這裡有幾個小技巧:
一、在php中,字元編碼是按所傳送的編碼為準的,因此使用的就是用戶輸入的編碼,不會自動改變,但在asp中,默認的編碼是unicode,這樣我們很容易就能得到gbk->unicode的編碼對照表,這樣即使在毫無基礎庫的情況下也能很容易的實現gbk到utf-8的轉換了;
二、由於GBK是高位最低數值是0x40,即是64,因此,有時候組織一些涉及中文的字串時,分割字元最好用64之前的
ascii碼 ,這樣在任意情況下替換或分割都不會出現
亂碼 ,比較常用的是 ","、";"、":"、" "、" "、" ",這些字元永遠都不會給gb編碼添亂。
體系 ASCII 我們日常接觸到的檔案分
ASCII 和Binary兩種。
ASCII 是“美國信息交換標準編碼”的英文字頭縮寫,可稱之為“美標”。美標規定了用從0到127的128個數字來代表信息的規範編碼,其中包括33個控制碼,一個空格碼,和94個形象碼。形象碼中包括了英文大小寫字母,阿拉伯數字,標點符號等。我們平時閱讀的英文電腦文本,就是以形象碼的方式傳遞和存儲的。美標是國際上大部分大小電腦的通用編碼。
然而電腦中的一個字元大都是用一個八位數的二進制數字表示。這樣每一字元便可能有256個不同的數值。由於美標只規定了128個編碼,剩下的另外128個數碼沒有規範,各家用法不一。另外美標中的33個控制碼,各廠家用法也不盡一致。這樣我們在不同電腦間交換檔案的時候,就有必要區分兩類不同的檔案。第一類檔案中每一個字都是美標形象碼或空格碼。這類檔案稱為“美標文本檔案”(ASCII Text Files),或略為“文本檔案”,通常可在不同
電腦系統 間直接交換。第二類檔案,也就是含有控制碼或非美標碼的檔案,通常不能在不同電腦系統間直接交換。這類檔案有一個通稱,叫“二進制檔案”(Binary Files)。
國標 “國標”是“
中華人民共和國國家標準 信息交換用漢字編碼”的簡稱。國標表(基本表)把七千餘漢字、以及標點符號、外文字母等,排成一個94行、94列的方陣。方陣中每一橫行叫一個“區”,每個區有九十四個“位”。一個漢字在方陣中的坐標,稱為該字的“
區位碼 ”。例如“中”字在方陣中處於第54區第48位,它的
區位碼 就是5448。
其實94這個數字。它是美標中形象碼的總數。國標表沿用這個數字,本意大概是要用兩個美標形象符代表一個漢字。由於美標形象符的編碼是從33到126,漢字區位碼如果各加上32,就會與美標形象碼的範圍重合。如上例“中”字區、位碼加上32後,得86,80。這兩個數字的十六進制放在一起得5650,稱為該字的“國標碼”,而與其相對應的兩個美標符號,VP,也就是“中”字的“國標符”了。
這樣就產生了一個如何區分國標符與美標符的問題。在一個中英文混用的檔案里,“VP”到底代表“中”字呢,還是代表某個英文字頭縮寫?電子工業部第六研究所開發CCDOS的時候,使用了一個簡便的解決方案:把國標碼的兩個數字各加上128,上升到非美標碼的位置。(改變後的國標碼,習慣上仍叫“國標”。)
這個方案固然解決了原來的問題,可是新的問題隨之產生。中文檔案成了“二進制檔案”,既不能可靠地在不同電腦系統間交換,也不與市場上大部分以美標符號為設計對象的
軟體兼容 。
為了區分以上兩種“國標”,我們把原與美標形象碼重合的國標碼稱為“純國標” ,而把CCDOS加上128的國標碼稱為“準國標”。
GBK GBK碼是
GB碼 的擴展字元編碼,對多達2萬多的簡繁漢字進行了編碼,簡體版的Win95和Win98都是使用GBK作系統內碼。
從實際運用來看,
微軟 自win95簡體中文版開始,系統就採用GBK代碼,它包括了TrueType
宋體 、
黑體 兩種
GBK字型檔 (北京中易電子公司提供),可以用於顯示和列印,並提供了四種GBK漢字的
輸入法 。此外,
瀏覽器 IE4.0簡體、繁體中文版內部提供了一個GBK-BIG5代碼雙向轉換功能。此外,
微軟公司 為IE提供的
語言包 中,簡體中文支持(Simplified Chinese Language Support Kit)的兩種
字型檔 宋體 、黑體,也是GBK漢字(
珠海 四通電腦排版系統開發公司提供)。其他一些中文字型檔生產廠商,也開始提供TrueType或PostScript GBK字型檔。
許多外掛式的中文平台,如
南極星 、四通利方(Richwin)等,提供GBK碼的支持,包括
字型檔 、
輸入法 和GBK與其他中文代碼的轉化器。
網際網路方面,許多網站網頁使用GBK代碼。
但是多數
搜尋引擎 都不能很好的支持GBK漢字搜尋,大陸地區的搜尋引擎有些能不完善的支持GBK漢字檢索。
其實,GBK是又一個漢字編碼標準,全稱《漢字內碼擴展規範》(Chinese Internatial Code Specification),1995年頒布。GB是國標,K是漢字“擴展”的漢語拼音第一個字母。
GBK向下與GB-2312編碼兼容,向上支持ISO 10646.1國際標準,是前者向後者過渡的一個承啟標準。
GBK規範收錄了ISO 10646.1中的全部CJK漢字和符號,並有所補充。具體包括:GB 2312中的全部漢字、非漢字元號;GB 13000.1中的其他CJK漢字。以上合計20902個GB化漢字;《簡化總表中》未收入GB 13000.1的52個漢字;《
康熙字典 》以及《辭海》中未被收入GB 13000.1的28個部首及重要構件;13個
漢字結構 符;BIG-5中未被GB 2312收入、但存在於GB 13000.1的139個圖形符號;GB 12345增補的6個拼音符號;GB 12345增補的19個豎排圖形符號(GB 12345較GB 2312增補豎排標點符號29個,其中10個未被GB 13000.1收入,故GBK亦不收);從GB 13000.1的CJK兼容區挑選出的21個漢字;GB 13000.1收入的31個IBM OS/2專用符號。GBK亦採用雙
位元組 表示,總體編碼範圍為0x8140~0xFEFE之間,首位元組在0x81~0xFE之間,尾位元組在0x40~0xFE之間,剔除0x××7F一條線,總計23940個碼位,共收入21886個漢字和圖形符號,其中漢字(包括部首和構件)21003個,圖形符號883個。
BIG5 BIG5碼是針對繁體漢字的漢字編碼,在台灣、
香港 的
電腦系統 中得到普遍套用。BIG5碼的編碼範圍參考下文。
HZ碼 HZ 碼是中國留學生為了使漢字信息能在網路上直接傳送而產生的。因目前大多數 (西方)網路系統為7位,最高位被禁止掉,因此 GB 碼無法被直接傳輸,HZ 碼是為了達到在7位網路系統中直接傳遞漢字信息的目的而規範的。
“HZ”方案的特點,是以“純國標”的中文與美標碼混用。那么“HZ”是怎樣區分國標符和美標符的呢?答案其實也很簡單:當一串美標碼中間插入一段國標碼的時候,我們便在國標碼的前面加上~,後面加上~。這些
附加碼 分別叫“逃出碼”和“逃入碼”。 由於這些
附加碼 本身也是美標形象碼,整個檔案就儼然是一個美標文本檔案,可以安然地 在電腦網上傳遞,也和大部分英文文本處理
軟體兼容 。
CJK碼 ISO-2022是
國際標準組織 (ISO)為各種語言字元制定的編碼標準。採用二個位元組編碼,其中漢語編碼稱ISO-2022 CN,日語、韓語的編碼分別稱JP、KR。一般將三者合稱CJK碼。CJK碼主要在Internet網路中使用。
ISO 1993年,國際標準ISO10646 定義了通用
字元集 (Universal Character Set, UCS)。 UCS 是所有其他字元集標準的一個超集。它保證與其他字元集是雙向兼容的。就是說, 如果你將任何文本字元串翻譯到 UCS格式,然後再翻譯回原編碼, 你不會丟失任何信息。
UCS 包含了用於表達所有已知語言的字元。不僅包括拉丁語,希臘語,斯拉夫語,希伯來語,阿拉伯語,亞美尼亞語和
喬治亞 語的描述, 還包括中文,
日文 和韓文這樣的象形文字,以及平假名,片假名,孟加拉語,
旁遮普語 果魯穆奇字元(Gurmukhi),
泰米爾語 , 印.埃納德語(Kannada),Malayalam,泰國語, 寮語, 漢語拼音(Bopomofo), Hangul,Devangari,Gujarati, Oriya,Telugu 以及其它語種。對於還沒有加入的語言, 由於正在研究怎樣在計算機中最好地編碼它們, 因而最終它們都將被加入。這些語言包括Tibetian,高棉語,Runic(古代
北歐 文字),
衣索比亞 語, 其他象形文字,以及各種各樣的印-歐語系的語言,還包括挑選出來的藝術語言比如 Tengwar,Cirth 和
克林貢語 (Klingon)。UCS 還包括大量的圖形的,印刷用的,數學用的和科學用的符號,包括所有由 TeX,Postscript,
MS-DOS ,MS-Windows, Macintosh, OCR
字型 , 以及許多其他字處理和出版系統提供的字元。
ISO 10646 定義了一個 31 位的
字元集 。 然而, 在這巨大的編碼空間中, 迄今為止只分配了前 65534 個碼位 (0x0000 到 0xFFFD)。這個UCS的16位子集稱為基本多語言面 (Basic Multilingual Plane, BMP)。 將被編碼在16位BMP以外的字元都屬於非常特殊的字元(比如象形文字), 且只有專家在歷史和科學領域裡才會用到它們。按當前的計畫, 將來也許再也不會有字元被分配到從0x000000到0x10FFFF這個覆蓋了超過100萬個潛在的未來字元的 21 位的編碼空間以外去了。ISO 10646-1標準第一次發表於1993年, 定義了字元集與 BMP 中內容的架構。定義 BMP以外的字元編碼的第二部分 ISO 10646-2 正在準備中, 但也許要過好幾年才能完成。新的字元仍
源源不斷 地加入到 BMP 中, 但已經存在的字元是穩定的且不會再改變了。
UCS 不僅給每個字元分配一個代碼, 而且賦予了一個正式的名字。表示一個 UCS 或 Unicode 值的十六進制數, 通常在前面加上 “U+”, 就象U+0041 代表字元“拉丁大寫字母A”。UCS字元U+0000到U+007F 與 US-ASCII(ISO 646) 是一致的, U+0000 到 U+00FF 與 ISO
8859-1 (Latin-1) 也是一致的。從 U+E000 到 U+F8FF,已經BMP 以外的大範圍的編碼是為私用保留的。
1993年,ISO10646中定義的USC-4 (Universal Character Set) ,使用了4 個位元組的寬度以容納足夠多的相當可觀的空間,但是這個過於肥胖的字元標準在當時乃至21世紀都有其不現實的一面,就是會過分侵占存儲空間並影響信息傳輸的效率。 與此同時,Unicode 組織於約 10 年前以 Universal, Unique和Uniform 為主旨也開始開發一個16位字元標準, 為避免兩種16位編碼的競爭,1992年兩家組織開始協商,以期折衷尋找共同點,這就是今天的 UCS-2 (BMP,Basic Multilingual Plane,16bit) 和Unicode,但它們仍然是不同的方案。
Unicode
關於Unicode我們需要追溯一下它產生的淵源。
當計算機普及到
東亞 時,遇到了使用表意字元而非字母語言的中、日、韓等國家。在這些國家使用的語言中常用字元多達幾千個,而原來字元採用的是單位元組編碼,一張代碼頁中最多容納的字元只有2^8=256個,對於使用表意字元的語言是在無能為力。既然一個位元組不夠,自然人們就採用兩個位元組,所有出現了使用雙位元組編碼的字元集(DBCS)。不過雙位元組字元集中雖然表意字元使用了兩個位元組編碼,但其中的ASCII碼和
日文 片假名等仍用單位元組表示,如此一來給
程式設計師 帶來了不小的麻煩,因為每當涉及到DBCS字元串的處理時,總是要判斷當中的一個位元組到底表示的是一個字元還是半個字元,如果是半個字元,那是前一半還是後一半?由此可見DBCS並不是一種非常好的解決方案。
人們在不斷尋找這更好的字元編碼方案,最後的結果就是Unicode誕生了。Unicode其實就是寬位元組字元集,它對每個字元都固定使用兩個位元組即16位表示,於是當處理字元時,不必擔心只處理半個字元。
Unicode在網路、Windows系統和很多大型
軟體 中得到套用。
編碼種類 編碼(Encoding)在認知上是解釋傳入的刺激的一種基本知覺的過程。技術上來說,這是一個複雜的、多階段的轉換過程,從較為客觀的感覺輸入(例如光、聲)到主觀上有意義的體驗。
字元編碼 (Character encoding)是一套法則,使用該法則能夠對自然語言的字元的一個集合(如字母表或音節表),與其他東西的一個集合(如號碼或電脈衝)進行配對。
文字編碼 文字編碼(Text encoding)使用一種標記語言來標記一篇文字的結構和其他特徵,以方便計算機進行處理。
語義編碼 語義編碼 (Semantics encoding),以正式語言乙對正式語言甲進行語義編碼,即是使用語言乙表達語言甲所有的辭彙(如程式或說明)的一種方法。
電子編碼 電子編碼(Electronic encoding)是將一個信號轉換成為一個代碼,這種代碼是被最佳化過的以利於傳輸或存儲。轉換工作通常由一個編解碼器完成。
PCM編碼 PCM 脈衝編碼調製是Pulse Code Modulation的縮寫。(又叫脈衝編碼調製):數字通信的編碼方式之一。主要過程是將話音、圖像等模擬信號每隔一定時間進行取樣,使其離散化,同時將抽樣值按分層單位四捨五入取整量化,同時將抽樣值按一組
二進制 碼來表示抽樣脈衝的幅值。
神經編碼 神經編碼(Neural encoding)是指信息在神經元中被如何描繪的方法。
記憶編碼 記憶編碼 (Memory encoding)是把感覺轉換成記憶的過程。
加密 加密 (Encryption)是為了保密而對信息進行轉換的過程。
解碼 解碼 (Transcoding)是將編碼從一種格式轉換到另一種格式的過程。
字元集編 碼轉換輕鬆實現
在
LINUX 上進行編碼轉換時,既可以利用iconv函式族編程實現,還可以利用iconv命令去實現,只不過後者是針對檔案的,也就是將指定檔案從一種編碼轉換為另一種編碼。
iconv函式族的頭檔案是iconv.h,使用前需包含之。
#include <iconv.h>
iconv函式族有三個函式,原型如下:
(1) iconv_t iconv_open(const char *tocode, const char *fromcode)
此函式說明將要進行哪兩種編碼的轉換,tocode是目標編碼,fromcode是原編碼,該函式返回一個轉換句柄,供以下兩個函式使用。
(2)
size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft)
此函式從inbuf中讀取字元,轉換後輸出到outbuf中,inbytesleft用以記錄還未轉換的字元數,outbytesleft用以記錄輸出緩衝的剩餘空間。 (3) int iconv_close(iconv_t cd)
此函式用於關閉轉換句柄,釋放資源。
例子1: 用C語言實現的轉換示例程式
/* f.c :代碼轉換示例C程式 */
#include <iconv.h>
#define OUTLEN 255
main()
{
char *in_utf8 = "姝e?ㄥ??瑁?"
char *in_gb2312 = "正在安裝"
char out[OUTLEN]
//unicode碼轉為gb2312碼
rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN)
printf("unicode-->gb2312 out=%sn",out)
//gb2312碼轉為unicode碼
rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN)
printf("gb2312-->unicode out=%sn",out)
}
//代碼轉換:從一種編碼轉為另一種編碼
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
memset(outbuf,0,outlen);
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
//UNICODE碼轉為GB2312碼
int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
//GB2312碼轉為UNICODE碼
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}
/* f.cpp : 代碼轉換示例C++程式 */
#include <iconv.h>
#include <iostream>
#define OUTLEN 255
using namespace std;
// 代碼轉換操作類
class CodeConverter {
private:
iconv_t cd;
public:
// 構造
CodeConverter(const char *from_charset,const char *to_charset) {
cd = iconv_open(to_charset,from_charset;
}
// 析構
~CodeConverter() {
iconv_close(cd);
}
// 轉換輸出
int convert(char *inbuf,int inlen,char *outbuf,int outlen) {
char **pin = &inbuf;
char **pout = &outbuf;
memset(outbuf,0,outlen);
return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
}
};
int main(int argc, char **argv)
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安裝";
char out[OUTLEN];
// utf-8-->gb2312
CodeConverter cc = CodeConverter("utf-8","gb2312");
cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN);
cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;
// gb2312-->utf-8
CodeConverter cc2 = CodeConverter("gb2312","utf-8");
cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN);
cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl;
}
二、利用iconv命令進行編碼轉換
LINUX上進行編碼轉換時,既可以利用iconv函式族編程實現,也可以利用iconv命令來實現,只不過後者是針對檔案的,即將指定檔案從一種編碼轉換為另一種編碼。
iconv命令用於轉換指定檔案的編碼,默認輸出到標準輸出設備,亦可指定輸出檔案。
用法: iconv [選項...] [檔案...]
有如下選項可用:
輸入/輸出格式規範:
-f, --from-code=名稱 原始文本編碼
-t, --to-code=名稱 輸出編碼
信息:
輸出控制:
-c 從輸出中忽略無效的字元
-o, --output=FILE 輸出檔案
-s, --silent 關閉警告
--verbose 列印進度信息
-?, --help 給出該系統求助列表
--usage 給出簡要的用法信息
-V, --version 列印程式版本號
例子:
iconv -f utf-8 -t gb2312 aaa.txt >bbb.txt
這個命令讀取aaa.txt檔案,從utf-8編碼轉換為gb2312編碼,其輸出定向到bbb.txt檔案。
小結: LINUX 為我們提供了強大的編碼轉換工具,給我們帶來了方便。