- 字符編碼 (Character encoding)
2. 字符集 (Character Set) )
一般情況,一種編碼方式對應一種字符集。如 ASCII,對應 ASCII 字符集。GBK 編碼方式對應 GBK 字符集。但是也有一種編碼方式,多種字符集的,Unicode 字符集有多種編碼方式,如 utf-8,utf-16 等。. 3. ASCII
ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼):使用 7 個 Bit 表示,共 128 個字符,剛好佔用了一個字節中的後 7 位,共包括33 個控制字符和 95 個可顯示字符。
. 4. ANSI
ANSI (一種字符編碼,此處不是表示美國國家標準學會的意思):ANSI 是爲了讓計算機支持更多的語言,而在 ASCII 的基礎上的一種擴展字符編碼。在不同語言操作上,ANSI 都表示當前計算機默認的編碼方式。如在簡體 Windows 操作下,ANSI 編碼代表 GBK 編碼;在繁體中文操作下,ANSI 編碼代表 Big5 編碼;在日文 Windows 操作系統中,ANSI 編碼代表 Shift_JIS 編碼;在英文操作系統下,ANSI 就是 ASCII 編碼。
. 5. MBCS
MBCS(Multi-Byte Character Set),早在 1980 年,中國就提出了使用 GB2312 編碼方式來描述漢字。後來其他東亞國家也利用這種方式擴展 ASCII 編碼字符集。臺灣地區 5 大
企業推出的繁體 Big5 碼,香港新加坡等後來也利用。日本韓國也相應推出了自己的編碼方式。其實在這裏,BIG5 既是編碼方式,也是字符集。
. 6. GB2312(Guo Biao 2312) )
用雙字節表示漢字,但是爲了完全兼容 ASCII。漢字區“高字節”範圍爲 0xB0-0xF7,漢字區“低字節”範圍 0xA1-0xFE,佔用的碼位 72*94=6768 個。
. 7. GBK(Guo Biao Kuozhan)
後來發現 GB2312 的字符依然不夠用,尤其是像“鎔”(朱鎔基)字打不出來。然後決定漢字區的低字節完全不兼容 ASCII,只要當前字符屬於漢字碼,那麼其後的字符也屬於漢字碼。這樣在兼容 GB2312 的基礎上,再添加了近兩萬字和字符(兼容繁體、日本漢字、韓國漢字等)。GBK 同樣也是一種編碼方式和字符集兩種意義合於一體。
. 8. GB18030
有兩版 GB18030-2000 和 GB18030-2005,是 GBK 的擴展版,並且完全兼容 GBK。GB18030和 utf-8 類似,是動態的,既有單字節字體,也有雙字節字節(BGK),也有三字節,四字節字符。Windows 默認支持的是 GBK,若要支持 GB18030,需要下載安裝單獨的支持包。
. 9. Big5 5
1984 年臺灣五家公司聯合創立,稱大五碼,英文 Big5。Big5 也是雙字節編碼方式,收錄了一萬多字符,但是沒有包含中文簡體。Big5 目前也被香港、新家坡等地區國家使用。Big5 保存的文本,在簡體操作系統下顯示亂碼,但是有些編輯器會自動識別,然後將其按 GBK 繁體字顯示,即可正常顯示。如 Notepad++即有此功能。
10. 全角
GBK 用兩個字節重新表示了一遍在 ASCII 中出現的字符,這些字符被叫全角字符。
11. 半角
出現在 ASCII 中的字符,被稱作半角字符。
12. e Unicode 字符集
Unicode 字符集是 1990 年提出的,能夠表示全世界所有國家的所有字符。但是支持Unicode 字符集的編碼方式都有多種,如 UTF-8,UTF-16 等。編碼方式雖然不同,但是
都是可以完整表示所有 Unicode 字符的。VS 裏默認的 Unicode 字符集是指 utf-16 編碼的,即固定雙字節爲一個字符。
13. UTF- -8 8
因爲 Unicode 能夠包含全球所有的字符,而 utf-8 又是其中比較節省字符存儲的一種實現方式。所以現在的網站,基本都是以 utf-8 編碼方式來存儲、傳輸和顯示了。UTF-8
是變字節長度的,用 1-6 個字節表示字符。用一個字符表示常見字符,用二個字節表示拉丁文、希臘文、西裏爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞等,用三字
符表示常見漢字等,四個字節的字符比較少見。UTF-8 既能很方便存儲英文,又能兼容全世界的字符,所以非常流行。
14. UTF- -8 8 解析算法
如果字節的第一位爲 0,則 B 爲 ASCII 碼,並且 Byte 獨立的表示一個字符;
如果字節的第一位爲 1,第二位爲 0,則 Byte 爲一個非 ASCII 字符(該字符由多個字節表示)中的一個字節,並且不爲字符的第一個字節編碼;
如果字節的前兩位爲 1,第三位爲 0,則 Byte 爲一個非 ASCII 字符(該字符由多個字節
表示)中的第一個字節,並且該字符由兩個字節表示;
如果字節的前三位爲 1,第四位爲 0,則 Byte 爲一個非 ASCII 字符(該字符由多個字節表示)中的第一個字節,並且該字符由三個字節表示;
如果字節的前四位爲 1,第五位爲 0,則 Byte 爲一個非 ASCII 字符(該字符由多個字節
表示)中的第一個字節,並且該字符由四個字節表示代碼頁(CodePag):代碼頁是字符集的數字值,不同的語言使用不同的代碼頁。例 如,ANSI
代碼頁爲 1252,日文代碼頁爲 932,簡體中文(GBK)代碼頁爲 936,繁體中文(Big5)代碼頁爲 950。
15. 語言包
系統默認的是 ANSI,但是同時也兼容 Unicode,這也是 Windows 的 API 有兩套。當系統識別到當前字符是 Unicode 時,會以對應的 Unicode 編碼方式去解碼,Windows 支持的是 utf-8。解碼之後,需要正確地顯示出相應的字形,這個時候就需要語言包。如果沒有語言包,會出現亂碼。英文操作下,東亞語言歸爲一類,需要單獨安裝,安裝時提示230MB。因爲語言包比較大,所以在英文操作系統下,默認沒有安裝東亞語言包的,即不能正確顯示 Unicode 下的東亞文字。至於語言包爲什麼這麼大,猜測語言包必須得描述這個字體是如何點鉤撇捺的等等。Windows 可以在控制面板中設置非 Unicode 程序顯示語言。
16. 大小端模式
由於 CPU 的緣故,存取數據分大端模式和小端模式,然後一些操作系統了軟件也會有這樣的區分。大端模式(Big-endian),是指數據的高字節,保存在內存的低地址中,而
數據的低字節,保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放。小端模式(Little-endian),
是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分
權值低,和我們的邏輯方法一致。
17. BOM(Byte Order Mark, 字節順序標記) )
有一些文本編輯工具支持 UTF-8(BOM),字符 U+FEFF 如果出現在字節流的開頭,則用來標識該字節流的字節序,是高位在前還是低位在前。接收者收到 FEFF,就表明這個字節
流是 Big-Endian 的;如果收到 FFFE,就表明這個字節流是 Little- Endian 的。Windows 文本默認的 Unicode 爲大端 utf-16 存儲,即以 FFFE 開頭。BOM 主要應用Windows 下,而在某些系統下可能會出錯,如 PHP 中容易讀錯。
編碼 | 以此標記 (十六進制) | 以此標記 (十進制) |
UTF-8 | EF BB BF | 239 187 191 |
UTF-16(大端序) | FE FF | 254 255 |
UTF-16(小端序) | FF FE | 255 254 |
UTF-32(大端序) | 00 00 FE FF | 0 0 254 255 |
UTF-32(小端序) | FF FE 00 00 | 255 254 0 0 |
UTF-8 和 GBK 同屬於多字節 MultiByte,Unicode 默認是 UTF-16,即寬字符,兩個字節。
GBK(ANSI)->Unicode->UTF-8,反向即 UTF-8->Unicode->GBK(ANSI)。
-
// 註釋:多字節包括GBK和UTF-8 int GBK2UTF8(char *szGbk,char *szUtf8,int Len) { // 先將多字節GBK(CP_ACP或ANSI)轉換成寬字符UTF-16 // 得到轉換後,所需要的內存字符數 int n = MultiByteToWideChar(CP_ACP,0,szGbk,-1,NULL,0); // 字符數乘以 sizeof(WCHAR) 得到字節數 WCHAR *str1 = new WCHAR[sizeof(WCHAR) * n]; // 轉換 MultiByteToWideChar(CP_ACP, // MultiByte的代碼頁Code Page 0, //附加標誌,與音標有關 szGbk, // 輸入的GBK字符串 -1, // 輸入字符串長度,-1表示由函數內部計算 str1, // 輸出 n // 輸出所需分配的內存 ); // 再將寬字符(UTF-16)轉換多字節(UTF-8) n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL); if (n > Len) { delete[]str1; return -1; } WideCharToMultiByte(CP_UTF8, 0, str1, -1, szUtf8, n, NULL, NULL); delete[]str1; str1 = NULL; return 0; }
//UTF-8 GBK int UTF82GBK(char *szUtf8,char *szGbk,int Len) { int n = MultiByteToWideChar(CP_UTF8, 0, szUtf8, -1, NULL, 0); WCHAR * wszGBK = new WCHAR[sizeof(WCHAR) * n]; memset(wszGBK, 0, sizeof(WCHAR) * n); MultiByteToWideChar(CP_UTF8, 0,szUtf8,-1, wszGBK, n); n = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); if (n > Len) { delete[]wszGBK; return -1; } WideCharToMultiByte(CP_ACP,0, wszGBK, -1, szGbk, n, NULL, NULL); delete[]wszGBK; wszGBK = NULL; return 0; }
19. 附ASCII碼圖表