一、 編碼
同一個字符在不同的編碼下會被編成不同長度的編碼,比如:
ACSII,每個字符對應一個字節,實際上只使用了7位,從00h-7Fh。只能表達128個字符。
GB2312,中文的一種編碼,每個字符使用兩個字節表示。
UTF-8, 可以表達所有unicode字符,每個字符可以用1-3個字節表示。
UTF-16, 可以表達所有unicode字符,每個字符可以用1-2個16位整數表示。
UTF-32, 可以表達所有unicode字符,每個字符可以用1個32位整數表示。
Windows內部支持以下編碼:
Code Page |
Name |
Display Name |
936 |
gb2312 |
Chinese Simplified (GB2312) |
1149 |
IBM01149 |
IBM EBCDIC (Icelandic-Euro) |
1200 |
utf-16 |
Unicode |
1201 |
unicodeFFFE |
Unicode (Big-Endian) |
1252 |
Windows-1252 |
Western European (Windows) |
10003 |
x-mac-korean |
Korean (Mac) |
10008 |
x-mac-chinesesimp |
Chinese Simplified (Mac) |
20127 |
us-ascii |
US-ASCII |
20936 |
x-cp20936 |
Chinese Simplified (GB2312-80) |
20949 |
x-cp20949 |
Korean Wansung |
28591 |
iso-8859-1 |
Western European (ISO) |
28598 |
iso-8859-8 |
Hebrew (ISO-Visual) |
38598 |
iso-8859-8-i |
Hebrew (ISO-Logical) |
50220 |
iso-2022-jp |
Japanese (JIS) |
50221 |
csISO2022JP |
Japanese (JIS-Allow 1 byte Kana) |
50222 |
iso-2022-jp |
Japanese (JIS-Allow 1 byte Kana - SO/SI) |
50225 |
iso-2022-kr |
Korean (ISO) |
50227 |
x-cp50227 |
Chinese Simplified (ISO-2022) |
51932 |
euc-jp |
Japanese (EUC) |
51936 |
EUC-CN |
Chinese Simplified (EUC) |
51949 |
euc-kr |
Korean (EUC) |
52936 |
hz-gb-2312 |
Chinese Simplified (HZ) |
54936 |
GB18030 |
Chinese Simplified (GB18030) |
57002 |
x-iscii-de |
ISCII Devanagari |
57003 |
x-iscii-be |
ISCII Bengali |
57004 |
x-iscii-ta |
ISCII Tamil |
57005 |
x-iscii-te |
ISCII Telugu |
57006 |
x-iscii-as |
ISCII Assamese |
57007 |
x-iscii-or |
ISCII Oriya |
57008 |
x-iscii-ka |
ISCII Kannada |
57009 |
x-iscii-ma |
ISCII Malayalam |
57010 |
x-iscii-gu |
ISCII Gujarati |
57011 |
x-iscii-pa |
ISCII Punjabi |
65000 |
utf-7 |
Unicode (UTF-7) |
65001 |
utf-8 |
Unicode (UTF-8) |
65005 |
utf-32 |
Unicode (UTF-32) |
65006 |
utf-32BE |
Unicode (UTF-32 Big-Endian) |
目前Windows的內核已經采用Unicode編碼,這樣在內核上可以支持全世界所有的語言文字。但是由於現有的大量程序和文檔都采用了某種特定語言的編碼,例如gb2312,Windows不可能不支持現有的編碼,而全部改用Unicode。
Windows使用上面表格所示的代碼頁(code page)來適應各個國家和地區。Windows使用默認代碼頁來表示當前操作系統的使用的語言,這可以在控制面板的“區域和語言選項”中選擇。一般中文windows操作系統,選擇“中文(中國)”,這樣設置,windows的默認代碼頁就是936,即gb2312。
Windows按照當前的缺省代碼頁去解釋文本文件里的字節流。缺省代碼頁可以通過控制面板的區域選項設置。記事本的另存為中有一項ANSI,其實就是按照缺省代碼頁的編碼方法保存。
Windows的內碼是Unicode,它在技術上可以同時支持多個代碼頁。只要文件能說明自己使用什么編碼,用戶又安裝了對應的代碼頁,Windows就能正確顯示,例如在HTML文件中就可以指定charset。
字節序
UTF-8是單字節的編碼,不用考慮字節順序,但是UTF-16和UTF-32是16位和32位的編碼,每個編碼內部都有個字節順序的問題。比如字符”A” (U+0041),在序列化時是”00”在前還是”41”在前,這就有兩種可能。
UTF-16 big-endian byte order: 00 41
UTF-16 little-endian byte order: 41 00
規范規定了一個可選的方案,就是在編碼前導幾個字符放上本身不是UTF可能編碼的前導編碼來幫助判斷識別。
UTF-8: EF BB BF
UTF-16 big-endian byte order: FE FF
UTF-16 little-endian byte order: FF FE
UTF-32 big-endian byte order: 00 00 FE FF
UTF-32 little-endian byte order: FF FE 00 00
二、 需要把string轉換為byte[]使用的場景
任何需要把string序列化處理都需要這種轉換,比如:
需要把string保存到文件中,必須把string轉換成一個有序的字節流,以便系統在硬盤上做物理保存。
對string做加密操作時,加密算法是針對字節進行處理,這時也需要把string轉換成字節流以便加密算法對數據進行處理。
String到字節流的轉換涉及到使用何種編碼,使用不同的編碼得到的字節碼不同,再從字節碼做反操作恢復成string,必須使用編碼時使用的編碼或者兼容的編碼,否則結果就是亂碼。
三、 string轉換為byte []的操作
1、 確定使用的編碼
使用Encoding類的靜態方法GetEncoding方法獲得某個類型的Encoding對象。
l public static Encoding.GetEncoding(int codepage)
codepage指定這種返回代碼頁的Encoding
l public static Encoding GetEncoding (string name)
name 指定這種返回代碼名的Encoding
其中使用到的代碼頁和代碼名在上面表中。
比如要獲得一個utf-8的Encoding對象
Encoding myEncoding = Encoding.GetEncoding("utf-8");
2、 從string到byte[]
string sData = “字符串”;
byte[] myByte = myEncoding.GetBytes(sData);
使用GetBytes方法時,不產生前面所說的識別不同UTF格式的前導符。
3、 從byte[]到string
byte[] myByte = new byte[]{};
string sData = myEncoding.GetString(byte[] myByte);