Unicode字符集和多字節字符集關係

Unicode字符集和多字節字符集關係

在計算機中字符通常並不是保存爲圖像,每個字符都是使用一個編碼來表示的,而每個字符究竟使用哪個編碼代表,要取決於使用哪個字符集(charset)。 
在最初的時候,Internet上只有一種字符集——ANSI的ASCII字符集,它使用7 bits來表示一個字符,總共表示128個字符,其中包括了英文字母、數字、標點符號等常用字符。之後,又進行擴展,使用8 bits表示一個字符,可以表示256個字符,主要在原來的7 bits字符集的基礎上加入了一些特殊符號例如製表符。 
後來,由於各國語言的加入,ASCII已經不能滿足信息交流的需要,因此,爲了能夠表示其它國家的文字,各國在ASCII的基礎上制定了自己的字符集,這些從ANSI標準派生的字符集被習慣的統稱爲ANSI字符集,它們正式的名稱應該是MBCS(Multi-Byte Chactacter System,即多字節字符系統)。這些派生字符集的特點是以ASCII 127 bits爲基礎,兼容ASCII 127,他們使用大於128的編碼作爲一個Leading Byte,緊跟在Leading Byte後的第二(甚至第三)個字符與Leading Byte一起作爲實際的編碼。這樣的字符集有很多,我們常見的GB-2312就是其中之一。 
例如在GB-2312字符集中,“連通”的編碼爲C1 AC CD A8,其中C1和CD就是Leading Byte。前127個編碼爲標準ASCII保留,例如“0”的編碼是30H(30H表示十六進制的30)。軟件在讀取時,如果看到30H,知道它小於128就是標準ASCII,表示“0”,看到C1大於128就知道它後面有一個另外的編碼,因此C1 AC一同構成一個整個的編碼,在GB-2312字符集中表示“連”。 
由於每種語言都制定了自己的字符集,導致最後存在的各種字符集實在太多,在國際交流中要經常轉換字符集非常不便。因此,提出了Unicode字符集,它固定使用16 bits(兩個字節、一個字)來表示一個字符,共可以表示65536個字符。將世界上幾乎所有語言的常用字符收錄其中,方便了信息交流。標準的Unicode稱爲UTF-16。後來爲了雙字節的Unicode能夠在現存的處理單字節的系統上正確傳輸,出現了UTF-8,使用類似MBCS的方式對Unicode進行編碼。注意UTF-8是編碼,它屬於Unicode字符集。Unicode字符集有多種編碼形式,而ASCII只有一種,大多數MBCS(包括GB-2312)也只有一種。Unicode的最初目標,是用1個16位的編碼來爲超過65000字符提供映射。但這還不夠,它不能覆蓋全部歷史上的文字,也不能解決傳輸的問題 (implantation head-ache's),尤其在那些基於網絡的應用中。已有的軟件必須做大量的工作來程序16位的數據。因此,Unicode用一些基本的保留字符制定了三套編碼方式。它們分別是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列來編碼的,用一個或幾個字節來表示一個字符。這種方式的最大好處,是UTF-8保留了ASCII字符的編碼做爲它的一部分,例如,在UTF-8和ASCII中,“A”的編碼都是0x41.UTF-16和UTF-32分別是Unicode的16位和32位編碼方式。考慮到最初的目的,通常說的Unicode就是指UTF-16。 
例如“連通”兩個字的Unicode標準編碼UTF-16 (big endian)爲:DE 8F 1A 90 
而其UTF-8編碼爲:E8 BF 9E E9 80 9A 
最後,當一個軟件打開一個文本時,它要做的第一件事是決定這個文本究竟是使用哪種字符集的哪種編碼保存的。軟件有三種途徑來決定文本的字符集和編碼: 
最標準的途徑是檢測文本最開頭的幾個字節,如下表: 

開頭字節 Charset/encoding 
EF BB BF UTF-8 
FE FF UTF-16/UCS-2, little endian 
FF FE UTF-16/UCS-2, big endian 
FF FE 00 00 UTF-32/UCS-4, little endian.

00 00 FE FF UTF-32/UCS-4, big-endian.例如插入標記後,連通”兩個字的UTF-16 (big endian)和UTF-8碼分別爲: 
FF FE DE 8F 1A 90 
EF BB BF E8 BF 9E E9 80 9A 
但是MBCS文本沒有這些位於開頭的字符集標記,更不幸的是,一些早期的和一些設計不良的軟件在保存Unicode文本時不插入這些位於開頭的字符集標記。因此,軟件不能依賴於這種途徑。這時,軟件可以採取一種比較安全的方式來決定字符集及其編碼,那就是彈出一個對話框來請示用戶,例如將那個“連通”文件拖到MS Word中,Word就會彈出一個對話框。 
如果軟件不想麻煩用戶,或者它不方便向用戶請示,那它只能採取自己“猜”的方法,軟件可以根據整個文本的特徵來猜測它可能屬於哪個charset,這就很可能不準了。使用記事本打開那個“連通”文件就屬於這種情況。 
我們可以證明這一點:在記事本中鍵入“連通”後,選擇“Save As”,會看到最後一個下拉框中顯示有“ANSI”,這時保存。當再當打開“連通”文件出現亂碼後,再點擊“File”->“Save As”,會看到最後一個下拉框中顯示有“UTF-8”,這說明記事本認爲當前打開的這個文本是一個UTF-8編碼的文本。而我們剛纔保存時是用ANSI字符集保存的。這說明,記事本猜測了“連通”文件的字符集,認爲它更像一個UTF-8編碼文本。這是因爲“連通”兩個字的GB-2312編碼看起來更像UTF-8編碼導致的,這是一個巧合,不是所有文字都這樣。可以使用記事本的打開功能,在打開“連通”文件時在最後一個下拉框中選擇ANSI,就能正常顯示了。反過來,如果之前保存時保存爲UTF-8編碼,則直接打開也不會出現問題。 
如果將“連通”文件放入MS Word中,Word也會認爲它是一個UTF-8編碼的文件,但它不能確定,因此會彈出一個對話框詢問用戶,這時選擇“簡體中文(GB2312)”,就能正常打開了。記事本在這一點上做得比較簡化罷了,這與這個程序的定位是一致的。 

需要提醒大家的是,部分Windows 2000字型無法顯示所有的Unicode字符。如果發現文件中缺少了某些字符,只需將其變更爲其它字型即可。 

big endian和little endian 

big endian和little endian是CPU處理多字節數的不同方式。例如“漢”字的Unicode編碼是6C49。那麼寫到文件裏時,究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big endian。還是將49寫在前面,就是little endian。 

“endian”這個詞出自《格列佛遊記》。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,其中一個皇帝送了命,另一個丟了王位。 

我們一般將endian翻譯成“字節序”,將big endian和little endian稱作“大尾”和“小尾”。 

Unicode big endian:在Big-endian處理器(如蘋果Macintosh電腦)上建立的Unicode文件中的文字位元組(存放單位)排列順序,與在Intel處理器上建立的文件的文字位元組排列順序相反。最重要的位元組擁有最低的地址,且會先儲存文字中較大的一端。爲使這類電腦的用戶能夠存取你的文件,可選擇Unicode big-endian格式。

#####################################################################

ANSI字符,UNICODE,寬字符,窄字符,多字節字符集

Unicode :寬字節字符集 
1. 如何取得一個既包含單字節字符又包含雙字節字符的字符串的字符個數? 
可以調用Microsoft Visual C++的運行期庫包含函數_mbslen來操作多字節(既包括單字節也包括雙字節)字符串。 
調用strlen函數,無法真正瞭解字符串中究竟有多少字符,它只能告訴你到達結尾的0之前有多少個字節。 
2. 如何對DBCS(雙字節字符集)字符串進行操作? 
函數 描述 
PTSTR CharNext ( LPCTSTR ); 返回字符串中下一個字符的地址 
PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一個字符的地址 
BOOL IsDBCSLeadByte( BYTE ); 如果該字節是DBCS字符的第一個字節,則返回非0值 
3. 爲什麼要使用Unicode? 
(1) 可以很容易地在不同語言之間進行數據交換。 
(2) 使你能夠分配支持所有語言的單個二進制.exe文件或DLL文件。 
(3) 提高應用程序的運行效率。 
Windows 2000是使用Unicode從頭進行開發的,如果調用任何一個Windows函數並給它傳遞一個ANSI字符串,那麼系統首先要將字符串轉換成Unicode,然後將Unicode字符串傳遞給操作系統。如果希望函數返回ANSI字符串,系統就會首先將Unicode字符串轉換成ANSI字符串,然後將結果返回給你的應用程序。進行這些字符串的轉換需要佔用系統的時間和內存。通過從頭開始用Unicode來開發應用程序,就能夠使你的應用程序更加有效地運行。 
Windows CE 本身就是使用Unicode的一種操作系統,完全不支持ANSI Windows函數
Windows 98 只支持ANSI,只能爲ANSI開發應用程序。 
Microsoft公司將COM從16位Windows轉換成Win32時,公司決定需要字符串的所有COM接口方法都只能接受Unicode字符串。 
4. 如何編寫Unicode源代碼? 
Microsoft公司爲Unicode設計了WindowsAPI,這樣,可以儘量減少代碼的影響。實際上,可以編寫單個源代碼文件,以便使用或者不使用Unicode來對它進行編譯。只需要定義兩個宏(UNICODE和_UNICODE),就可以修改然後重新編譯該源文件。 
_UNICODE宏用於C運行期頭文件,而UNICODE宏則用於Windows頭文件。當編譯源代碼模塊時,通常必須同時定義這兩個宏。 
5. Windows定義的Unicode數據類型有哪些? 
數據類型 說明 
WCHAR Unicode字符 
PWSTR 指向Unicode字符串的指針 
PCWSTR 指向一個恆定的Unicode字符串的指針 
對應的ANSI數據類型爲CHAR,LPSTR和LPCSTR。 
ANSI/Unicode通用數據類型爲TCHAR,PTSTR,LPCTSTR。 
6. 如何對Unicode進行操作? 
字符集 特性 實例 
ANSI 操作函數以str開頭 strcpy 
Unicode 操作函數以wcs開頭 wcscpy 
MBCS 操作函數以_mbs開頭 _mbscpy

ANSI/Unicode 操作函數以_tcs開頭 _tcscpy(C運行期庫) 
ANSI/Unicode 操作函數以lstr開頭 lstrcpy(Windows函數)
所有新的和未過時的函數在Windows2000中都同時擁有ANSI和Unicode兩個版本。ANSI版本函數結尾以A表示;Unicode版本函數結尾以W表示。Windows會如下定義: 
#ifdef UNICODE 
#define CreateWindowEx CreateWindowExW 
#else 
#define CreateWindowEx CreateWindowExA 
#endif // !UNICODE 
7. 如何表示Unicode字符串常量? 
字符集 實例 
ANSI “string” 
Unicode L“string” 
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ } 
8. 爲什麼應當儘量使用操作系統函數? 
這將有助於稍稍提高應用程序的運行性能,因爲操作系統字符串函數常常被大型應用程序比如操作系統的外殼進程Explorer.exe所使用。由於這些函數使用得很多,因此,在應用程序運行時,它們可能已經被裝入RAM。 
如:StrCat,StrChr,StrCmp和StrCpy等。 
9.如何編寫符合ANSI和Unicode的應用程序? 
(1) 將文本串視爲字符數組,而不是chars數組或字節數組。 
(2) 將通用數據類型(如TCHAR和PTSTR)用於文本字符和字符串。 
(3) 將顯式數據類型(如BYTE和PBYTE)用於字節、字節指針和數據緩存。 
(4) 將TEXT宏用於原義字符和字符串。 
(5) 執行全局性替換(例如用PTSTR替換PSTR)。 
(6) 修改字符串運算問題。例如函數通常希望在字符中傳遞一個緩存的大小,而不是字節。
這意味着不應該傳遞sizeof(szBuffer),而應該傳遞(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要爲字符串分配一個內存塊,並且擁有該字符串中的字符數目,那麼請記住要按字節來分配內存。這就是說,應該調用malloc(nCharacters *sizeof(TCHAR)),而不是調用malloc(nCharacters)。 

10. 如何對字符串進行有選擇的比較? 
通過調用CompareString來實現。 
標誌 含義 
NORM_IGNORECASE 忽略字母的大小寫 
NORM_IGNOREKANATYPE 不區分平假名與片假名字符 
NORM_IGNORENONSPACE 忽略無間隔字符 
NORM_IGNORESYMBOLS 忽略符號 
NORM_IGNOREWIDTH 不區分單字節字符與作爲雙字節字符的同一個字符 
SORT_STRINGSORT 將標點符號作爲普通符號來處理 
11. 如何判斷一個文本文件是ANSI還是Unicode? 
判斷如果文本文件的開頭兩個字節是0xFF和0xFE,那麼就是Unicode,否則是ANSI。 
12. 如何判斷一段字符串是ANSI還是Unicode? 
用IsTextUnicode進行判斷。IsTextUnicode使用一系列統計方法和定性方法,以便猜測緩存的內容。由於這不是一種確切的科學方法,因此 IsTextUnicode有可能返回不正確的結果。 
13. 如何在Unicode與ANSI之間轉換字符串? 
Windows函數MultiByteToWideChar用於將多字節字符串轉換成寬字符串;

函數WideCharToMultiByte將寬字符串轉換成等價的多字節字符串。

#define CSTR_TO_WSTR(pcstr, pwstr, len) MultiByteToWideChar(0, 0, pcstr, strlen(pcstr), pwstr, len)
#define WSTR_TO_CSTR(pwstr, pcstr, len) WideCharToMultiByte(0, 0, pwstr, wcslen(pwstr), pcstr, len, NULL, NULL)

函數原型:
int WideCharToMultiByte(
UINT CodePage, //指定執行轉換的代碼頁
DWORD dwFlags, //允許你進行額外的控制,它會影響使用了讀音符號(比如重音)的字符
LPCWSTR lpWideCharStr, //指定要轉換爲寬字節字符串的緩衝區
int cchWideChar, //指定由參數lpWideCharStr指向的緩衝區的字符個數
LPSTR lpMultiByteStr, //指向接收被轉換字符串的緩衝區
int cchMultiByte, //指定由參數lpMultiByteStr指向的緩衝區最大值
LPCSTR lpDefaultChar, //遇到一個不能轉換的寬字符,函數便會使用pDefaultChar參數指向的字符
LPBOOL pfUsedDefaultChar //至少有一個字符不能轉換爲其多字節形式,函數就會把這個變量設爲TRUE
);
函數原型:
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCSTR lpMultiByteStr,
int cchMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar
);



________________________________________________________________

UCS,UNICODE和UTF-8

UCS,UNICODE和UTF-8

本文簡單介紹UCS,UNICODE和UTF-8,並利用C語言實現了UTF-8與UCS2之間的互相轉化。
1.什麼是UCS和ISO10646?
國際標準ISO10646定義了通用字符集(Universal Character Set, UCS). UCS是所有其它字符集標準的一個超集,它保證也其它字符集雙向兼容,即編碼間相互轉換不會丟失任何信息。UCS字符集U+0000到U+007F與US-ASCII是一致的。 
2.什麼是UNICODE
歷史上, 有兩個獨立的, 創立單一字符集的嘗試. 一個是國際標準化組織(ISO)的 ISO 10646 項目, 另一個是由(一開始大多是美國的)多語言軟件製造商組成的協會組織的 Unicode 項目. 幸運的是, 1991年前後, 兩個項目的參與者都認識到, 世界不需要兩個不同的單一字符集. 它們合併雙方的工作成果, 併爲創立一個單一編碼表而協同工作. 兩個項目仍都存在並獨立地公佈各自的標準, 但 Unicode 協會和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 標準的碼錶兼容, 並緊密地共同調整任何未來的擴展.
3.什麼是UTF-8(一種傳送和存儲格式)
UCS和UNICODE爲每個字符分配了一個對應的整數,但並沒有明確說明其實現機制.故存在多種編碼方式,其中以兩個字節和四個字節來存儲一個字符的方法分別叫UCS-2, UCS-4,要將一個ASCII文件轉換成一個UCS-2文件只要在每個字節前加一個字節0X00,轉換成UCS-4只要在每個字節前加三個0X00。
internet上大量的信息是以ASCII碼存在的,如果都用兩個字節來存儲將浪費大量的資源,同時Unix和Linux下使用USC-2和USC-4會導致嚴重問題,於是出現了UTF-8(定義於ISO10646-1).
UTF-8

(UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.)
UNICODE(UCS)和UTF-8的對應關係
U-00000000 - U-0000007F0xxxxxxx (ASCII碼 最重用)
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx (第二優先級常用)
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-04000000 - U-7FFFFFFF111111010xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (很少用)
在多字節串中,第一個字節的開頭‘1’的數目就是整個串中字節的數目.
下面舉UCS-2與UTF-8的對應關係,並利用C語言實現之間的互相轉化。
-----------------------------------------------------------------------------------------------------------
| UCS2 | UTF-8 |
|----------------------------------------------------------------------------------------------------------
| | code | 1st Byte | 2nd byte | 3rd Byte |
|--------------------------------------------------------------------------------------------------------
| 000000000aaaaaaa | 0000 - 007F | 0aaaaaaa | | |
|--------------------------------------------------------------------------------------------------------
| 00000bbbbbaaaaaa | 0080 - 07FF | 110bbbbb | 10aaaaaa | |
|--------------------------------------------------------------------------------------------------------
ccccbbbbbbaaaaaa | 0800 - FFFF | 1110cccc | 10bbbbbb | 10aaaaaa |
|--------------------------------------------------------------------------------------------------------

alphajay的疑問: 這裏是a b c應該是從0 1中取的一個bit位吧

因爲USC-2 每個字符用兩個字節 16bit表示


在這兒我只實現了單個字符的轉換,串的轉換也是一樣的道理。
1,把一個UTF-8字符轉換成一個UCS-2字符。
如果轉換成功返回1,如果UTF-8字符是一個unrecognized字符,則返回0,且存一個blackbox(U+22e0)到ucs2_code_ptr中。

typedef unsigned short UINT16;
typedef unsigned char UINT8;
typedef unsigned char BOOL;
#define TRURE (BOOL)(1)
#define FALSE (BOOL)(0)
BOOL UTF8toUCS2Code(const UINT8* utf8_code, UINT16* ucs2_code){
UINT16 temp1, temp2;
BOOL is_unrecognized = FALSE ;
UINT16 * in = utf8_code;
if(!utf8_code || !ucs2_code){
return is_unrecognized;
}

if(0x00 == (*in & 0x80)){
/* 1 byte UTF-8 Charater.*/
*ucs2_code= (UINT16)*in;
is_unrecognized = TRUE;
}
else if(0xc0 == (*in & 0xe0) &&
0x80 == (*(in + 1) & 0xc0)
){
/* 2 bytes UTF-8 Charater.*/ 
temp1 = (UINT16)(*in & 0x1f);
temp1 <<= 6;
temp1 |= (UINT16)(*(in + 1) & 0x3f);
*ucs2_code = temp1;
is_unrecognized = TRUE;
}
else if( 0xe0 == (*in & 0xf0) &&
0x80 == (*(in +1) & 0xc0) &&
0x80 == (*(in + 2) & 0xc0)
){
/* 3bytes UTF-8 Charater.*/
temp1 = (UINT16)(*in &0x0f);
temp1 <<= 12;
temp2 = (UINT16)(*(in+1) & 0x3F);
temp2 <<= 6;
temp1 = temp1 | temp2 | (UINT16)(*(in+2) & 0x3F);
*ucs2_code = temp1;
is_unrecognized = TRUE;
}
else{
/* unrecognize byte. */ 
*ucs2_code = 0x22e0;
is_unrecognized = FALSE;
}
return is_unrecognized;
}
2,把一個UCS-2字符轉換成UTF-8字符。函數返回轉換成UTF-8的長度(字節1 -- 3),如果目標指針爲空,返回0。
UINT8 UCS2toUTF8Code(UINT16 ucs2_code, UINT8* utf8_code){
int length = 0;
UINT8* out = utf8_code;
if(!utf8_code){
return length;
}
if(0x0080 > ucs2_code){
/* 1 byte UTF-8 Character.*/
*out = (UINT8)ucs2_code;
length++; 
}
else if(0x0800 > ucs2_code){
/*2 bytes UTF-8 Character.*/
*out = ((UINT8)(ucs2_code >> 6)) | 0xc0;
*(out+1) = ((UINT8)(ucs2_code & 0x003F)) | 0x80;
length += 2;
}
else{
/* 3 bytes UTF-8 Character .*/
*out = ((UINT8)(ucs2_code >> 12)) | 0xE0;
*(out+1) = ((UINT8)((ucs2_code & 0x0FC0)>> 6)) | 0x80;
*(out+2) = ((UINT8)(ucs2_code & 0x003F)) | 0x80;
length += 3; 
}
return length;
}
字符串間的轉換也是一樣的。

[概述]
計算機中的一切都是以數字來表示的,字符同樣如此。字符編碼就是將字符集編碼成爲數字序列,以便能讓計算機識別。各個地區和國家使用的語言有別,將本地使用的語言符號進行編碼就得到本地編碼字符集。例如西歐國家使用的本地編碼是ISO8859-1,中國大陸和新加坡等地區使用本地編碼是GB2312或GBK,中國港臺地區使用的本地編碼是BIG5,韓國和日本的本地編碼分別是euc-kr和Shift_JIS。電腦的操作系統支持各種本地編碼字符集,操作系統默認的本地編碼和你所安裝的操作系統語言版本是一致的。本地集只對本地使用的文字符號進行了編碼,並不包括其他地區使用的文字,即使兩個本地集中包含了相同的字符,這個字符的編碼值也是不同的。例如“中”的GB2312或GBK編碼值爲“0xD6D0”,而BIG5編碼值爲“0xA4A4”。
全球信息交流與融合的趨勢要求實現對本地字符集的統一,1984年4月ISO成立了工作組,針對各國文字、符號進行統一編碼,這種編碼成爲Unicode。Unicode於1992年6月通過DIS(DrafInternationalStandard),V2.0版本於1996年發佈。Unicode編碼包括了符號6811個、漢字20902個、韓文11172個、等等。Unicode雖然實現了全球統一編碼,但是在字符集數量和編碼效率方面顯然存在着不足,而UTF-8、UTF-16就是針對Unicode編碼進行轉換或擴充形成的編碼,UTF是Unicode Translation Format的縮寫。

[細節]
關於ASCII編碼
ASCII編碼是美國標準信息交換碼,這種編碼方式針對的是英文字符。ASCII編碼使用一個字節對字符進行編碼,而且字節的最高位都爲0,因此ASCII編碼的字符集大小是128個。由於英文字母僅有26個,再加上其他一些常用符號,總大小也不會超過128個,因此ASCII編碼的空間是足夠的。例如,字符“a”被編碼爲0x61,字符“b”被編碼爲0x62等等。注意,在有的時候ASCII泛指本地編碼,例如文本編輯器UltraEdit中有諸如“ASCII轉Unicode”的功能,這裏的ASCII就泛指本地編碼,如果本地編碼是GBK,這個功能執行的就是GBK編碼到Unicode編碼的轉換。

關於ISO8859-1編碼
ISO8859-1是西歐語系國家通用的字符集編碼,ISO8859-1使用一個字節對字符進行編碼,編碼值範圍是0x00-0xFF。其中,0x00-0x1F用作控制字,0x20-0x7F表示字母、數字和符號這些圖形字符,0xA0-0xFF作爲附加部分使用。由於ASCII編碼只使用了一個字節中的低7位,編碼範圍僅爲0-127,雖然可以容納英文字符和其他的一些符號,但是卻不能包含除英文以外的其他西歐語言的字母,因此ASCII編碼在西歐國家並不通用。針對這個問題ISO在ASCII編碼的基礎上進行了擴充,制定了ISO8859-1編碼,ISO8859-1編碼使用了一個字節的全部8位,編碼範圍是0-255,能包含西歐語系的所有字母和符號。

關於GB2312、GBK和BIG5編碼
GB2312碼是中華人民共和國國家漢字信息交換使用碼,全稱《信息交換使用漢字編碼字符集-基本集》,由國家標準總局發佈,1981年5月1日實施,中國大陸和新加坡等地使用此編碼。GB2312收錄了簡化漢字、符號、字母、日文假名等共計7445個字符,其中漢字佔6763個。GB2312將代碼表分區94個區(0xA1-0xFE),對應第一個字節,每個區94個位(0xA1-0xFE),對應了第二字節,兩個字節的值分別爲區號的值和位號的值加32(0x20),因此也被稱爲區位碼。GB2312的編碼範7圍是0x2121-0x777E,與ASCII有重疊,通常方法是將GB碼的兩個字節的最高位置1區別
GBK是GB2312-80的擴展,向上兼容,包含了20902個漢字,編碼範圍是0x8140-0xFEFE,剔除高位0x80的字位,其他字符都可以一一映射到Unicode2.0。GB18030-2000(GBK2K)在GBK的基礎上增加了藏、蒙等少數民族的字符,GBK2K從根本上解決了字位不夠、字形不足的問題。GBK2K首先要求實現能夠完全映射到Unicode3.0標準的所有字形,現在還沒有任何一個操作系統支持GBK2K。
BIG5碼被稱爲大五碼,是中國港臺地區使用的字符編碼方式。TW-BIG5碼將所有字分爲兩大羣,即常用字區和次常用字區,每個字區分都採用筆畫排序,同筆畫的字依部首排序。TW-BIG5每個字由兩個字節組成


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章