首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

字符編碼深度解析:從 ASCII 到 UTF-8 的演進與 C# 實戰

     編輯:關於C#

為什麼要理解字符編碼?

亂碼是開發者的噩夢。無論是讀取文件、網頁顯示、資料庫存儲,還是 API 串接,編碼不一致都會導致數據損壞。本文從歷史演進角度,梳理 ASCII、擴展編碼、Unicode 到 UTF-8 的來龍去脈,並給出 C# 實戰代碼。

一、ASCII 碼:一切的起點

1960 年代美國制定的 ASCII 碼,用 7 位元表示 128 個字符(含 32 個控制字符),最高位固定為 0。例如:空格 32 (00100000)、大寫 A 65 (01000001)、小寫 a 97 (1100001)。

string s = "a";
byte[] ascii = Encoding.ASCII.GetBytes(s); // [97]

二、非 ASCII 編碼:各自為政的混亂期

歐洲語言需要變音符號,便利用第 8 位擴展到 256 個字符。但同一個字節值在不同語系代表不同字符:130 在法語是 é,希伯來語卻是 Gimel,俄語又不同。中文更嚴重,漢字超過 10 萬,必須用多字節編碼(如 GB2312 雙字節,理論容納 65536 字符)。

string s = "梁";
Encoding gb2312 = Encoding.GetEncoding("GB2312");
byte[] gb = gb2312.GetBytes(s); // [193, 186]

三、Unicode:統一字符集的誕生

Unicode 為全球所有字符分配唯一碼位(目前超過 100 萬),解決「同碼異字」問題。但它只定義碼位,不定義存儲方式。

string s = "梁";
byte[] unicode = Encoding.Unicode.GetBytes(s); // [129, 104] (小端序 0x6881)

四、Unicode 的兩大難題

  1. 如何區分邊界:三個字節是一個字符還是三個 ASCII?
  2. 空間浪費:英文若強制 3-4 字節,文件體積膨脹 2-3 倍。

導致出現多種存儲格式(UTF-8、UTF-16、UTF-32),且 Unicode 長期難以推廣,直到互聯網普及。

五、UTF-8:互聯網的事實標準

UTF-8 是 Unicode 的一種變長實現:1-4 字節動態編碼。

編碼規則

  • 單字節:首位 0,後 7 位即 Unicode 碼(兼容 ASCII)
  • N 字節 (N>1):首字節前 N 位為 1,第 N+1 位為 0;後續字節均以 10 開頭;剩餘位填 Unicode 碼

範例:「梁」字編碼過程

string s = "梁";
byte[] utf8 = Encoding.UTF8.GetBytes(s); // [230, 162, 129] = 0xE6 0xA2 0x81

Unicode 0x6881 落在 U+0800~U+FFFF 區間,採用 3 字節模板 1110xxxx 10xxxxxx 10xxxxxx,從低位向高位填入得 11100110 10100010 10000001。

六、C# 編碼轉換實戰

UTF-8 轉 GB2312

string UTF8ToGb2312(string str) 
{
    Encoding utf8 = Encoding.UTF8;
    Encoding gb2312 = Encoding.GetEncoding("gb2312");
    byte[] unicodeBytes = utf8.GetBytes(str);
    byte[] gbBytes = Encoding.Convert(utf8, gb2312, unicodeBytes);
    char[] chars = new char[gb2312.GetCharCount(gbBytes, 0, gbBytes.Length)];
    gb2312.GetChars(gbBytes, 0, gbBytes.Length, chars, 0);
    return new string(chars);
}

七、編碼選擇建議與亂碼排查

  • 新專案優先 UTF-8:跨平台、跨語言、無需語言包
  • 舊系統維護:GB2312/Big5 仍常見於中文舊專案
  • 亂碼核心原因:讀取時編碼與寫入時不一致。.NET 內存字符串皆為 Unicode,ASP.NET 預設 UTF-8,出現亂碼先檢查解碼端編碼設定

關鍵對照表

編碼字節長度適用場景C# 類
ASCII1 字節純英文Encoding.ASCII
GB23122 字節簡體中文舊系統Encoding.GetEncoding("GB2312")
Unicode (UTF-16LE)2/4 字節.NET 內存內部Encoding.Unicode
UTF-81-4 字節Web、API、現代應用Encoding.UTF8

理解編碼本質,亂碼就不再是不可解之謎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved