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

常見字元編碼深度解析:UCS、Unicode、UTF-8/7、GB2312 與 URL 解碼

     編輯:關於VC++

一、通用字符集(UCS,ISO/IEC 10646-1)

  • UCS-4:每字元 4 位元組(32 位元),理論支援超大字符集。
  • UCS-2:每字元 2 位元組(16 位元),僅涵蓋基本多語言面(BMP,0x0000~0xFFFD)。

二、基本多語言面(BMP)

ISO 10646 定義 31 位元字符空間,目前僅分配前 65534 碼位(BMP),即 UCS-2 可編址範圍。

三、Unicode 編碼標準

ISO 10646 與 Unicode Consortium 1991 年合併,碼表保持兼容。Unicode 額外定義語意屬性(排版、雙向演算法等),為高品質排版系統提供參考。

四、UTF-8:網頁與傳輸的事實標準

解決 UCS-2/4 在 8 位元環境下的不相容問題。特性:

  1. ASCII 字元(0x00~0x7F)單位元組編碼,完全相容。
  2. 多位元組序列首位元組高位標示總長度(110xxxxx 兩字節、1110xxxx 三字節…)。
  3. 位元組值 0xFE、0xFF 永不出現,避免與 BOM 混淆。
  4. 字元邊界易於掃描識別。

UTF-8 編碼規則表

UCS-4 範圍UTF-8 位元組序列
0000 0000 ~ 0000 007F0xxxxxxx
0000 0080 ~ 0000 07FF110xxxxx 10xxxxxx
0000 0800 ~ 0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000 ~ 001F FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000 ~ 03FF FFFF111110xx 10xxxxxx ...
0400 0000 ~ 7FFF FFFF1111110x 10xxxxxx ...

Unicode (UCS-2) ↔ UTF-8 互轉 C++ 實現

// Unicode → UTF-8
int UnicodeToUTF8(WCHAR ucs2, unsigned char* buffer) {
    memset(buffer, 0, 4);
    if (ucs2 <= 0x007F) { buffer[0] = (char)ucs2; return 1; }
    if (ucs2 <= 0x07FF) {
        buffer[1] = 0x80 | (ucs2 & 0x3F);
        buffer[0] = 0xC0 | ((ucs2 >> 6) & 0x1F);
        return 2;
    }
    // 0x0800 ~ 0xFFFF
    buffer[2] = 0x80 | (ucs2 & 0x3F);
    buffer[1] = 0x80 | ((ucs2 >> 6) & 0x3F);
    buffer[0] = 0xE0 | ((ucs2 >> 12) & 0x0F);
    return 3;
}

// UTF-8 → Unicode
WCHAR UTF8ToUnicode(unsigned char* buffer) {
    WCHAR temp = 0;
    if (buffer[0] < 0x80) return buffer[0];
    if (buffer[0] < 0xE0) {  // 2 bytes
        temp = (buffer[0] & 0x1F) << 6 | (buffer[1] & 0x3F);
    } else if (buffer[0] < 0xF0) {  // 3 bytes
        temp = (buffer[0] & 0x0F) << 12 | (buffer[1] & 0x3F) << 6 | (buffer[2] & 0x3F);
    } else return 0xFEFF;  // 非首位元組或超過 3 字節
    return temp;
}

注意:解碼需加入安全檢查,防範非法序列(如 0xC0 0x80 解碼為 U+0000 導致緩衝區溢位)。

五、UTF-7:郵件安全傳輸格式(RFC 1642)

  • 英文字母、數字、常見符號直接顯示;其餘採修改版 Base64 編碼。
  • + 啟始編碼,- 結束;+- 代表字面 +。
  • 實作關鍵:狀態機(ASCII 模式 / Base64 模式 / AFTER_PLUS),位元緩衝區累積 6 位元輸出 Base64 字母表字元。

文中提供完整 UnicodeToUTF7 / UTF7ToUnicode 狀態機實作,含哈希表加速字元分類與 Base64 反查。

六、GB2312 國標碼與機內碼

  • 區位碼:1~94 區,每區 94 字。1~15 區為符號,16~55 一級漢字,56~87 二級漢字。
  • 國標碼 = 區位碼 + 0x2020。
  • 機內碼 = 國標碼 + 0x8080 = 區位碼 + 0xA0A0。
  • 判斷漢字啟發式:位元組高位 ≥ 0xA0 多為漢字,但有例外(如「鎔」編碼 0xE946,次位元組 0x46 < 0xA0)。

七、Windows 多位元組與 Unicode 互轉 API

// Unicode → 多位元組 (GB2312/UTF-8/UTF-7)
int UnicodeToGB2312(char** dest, const WCHAR* src) {
    int size = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
    *dest = new char[size];
    return WideCharToMultiByte(CP_ACP, 0, src, -1, *dest, size, NULL, NULL);
}
// 多位元組 → Unicode
int Gb2312ToUnicode(WCHAR** dest, const char* src) {
    int len = strlen(src);
    *dest = new WCHAR[len + 1];
    int ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, len, *dest, len);
    (*dest)[ret] = 0;
    return ret;
}

代碼頁參數:CP_ACP(系統預設)、CP_UTF7 (65000)、CP_UTF8 (65001)。

八、URL 解碼實戰(IE GET 請求為 UTF-8 編碼)

CString UrlToString(CString url) {
    CString str; url.MakeLower();
    for (int i=0; i

結語

本文系統梳理 UCS/Unicode/UTF/GB2312 編碼體系與互轉算法,附實戰 C++ 代碼,另補充 MIME 等編碼請自行查閱。

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