C++ UTF8編碼轉換 CChineseCode

來源:互聯網
上載者:User

一 預備知識 
1,字元:字元是抽象的最小文本單位。它沒有固定的形狀(可能是一個字形),而且沒有值。“A”是一個字元,“€”(德國、法國和許多其他歐洲國家通用貨幣的標誌)也是一個字元。“中”“國”這是兩個漢字字元。字元僅僅代表一個符號,沒有任何實際值的意義。 
2,字元集:字元集是字元的集合。例如,漢字字元是中國人最先發明的字元,在中文、日文、韓文和越南文的書寫中使用。這也說明了字元和字元集之間的關係,字元組成字元集(iso8859-1,GB2312/GBK,unicode)。 
3,代碼點:字元集中的每個字元都被分配到一個“代碼點”。每個代碼點都有一個特定的唯一數值,稱為標值。該標量值通常用十六進位表示。 
4,代碼單元: 在每種編碼形式中,代碼點被映射到一個或多個代碼單元。“代碼單元”是各個編碼方式中的單個單元。代碼單元的大小等效於特定編碼方式的位元: 
UTF-8 :UTF-8 中的代碼單元由 8 位組成;在 UTF-8 中,因為代碼單元較小的緣故,每個代碼點常常被映射到多個代碼單元。代碼點將被映射到一個、兩個、三個或四個代碼單元; 
UTF-16 :UTF-16 中的代碼單元由 16 位組成;UTF-16 的代碼單元大小是 8 位代碼單元的兩倍。所以,標量值小於 U+10000 的代碼點被編碼到單個代碼單元中; 
UTF-32:UTF-32  中的代碼單元由 32 位組成; UTF-32 中使用的 32 位代碼單元足夠大,每個代碼點都可編碼為單個代碼單元; 
GB18030:GB18030  中的代碼單元由 8 位組成;在 GB18030 中,因為代碼單元較小的緣故,每個代碼點常常被映射到多個代碼單元。代碼點將被映射到一個、兩個或四個代碼單元。 
5,舉例: 
“中國北京香蕉是個大笨蛋”這是我定義的aka字元集;各字元對應代碼點為: 
北 00000001 
京 00000010 
香 10000001 
蕉 10000010 
是 10000100 
個 10001000 
大 10010000 
笨 10100000 
蛋 11000000 
中 00000100 
國 00001000 
下面是我定義的 zixia 編碼方案(8位),可以看到它的編碼中表示了aka字元集的所有字元對應的 代碼單元; 
北 10000001 
京 10000010 
香 00000001 
蕉 00000010 
是 00000100 
個 00001000 
大 00010000 
笨 00100000 
蛋 01000000 
中 10000100 
國 10001000 
所謂文字檔 就是我們按一定編碼方式將位元據表示為對應的文本如 00000001000000100000010000001000000100000010000001000000這樣的檔案。我用一個支援 zixia編碼和aka字元集的記事本開啟,它就按照編碼方案顯示為  “香蕉是個大笨蛋 ” 
如果我把這些字元按照GBK另存一個檔案,那麼則肯定不是這個,而是 
1100111111100011 1011110110110110 1100101011000111 1011100011110110 1011010011110011 1011000110111111 1011010110110000 110100001010 
二,字元集 
1, 常用字元集分類 
ASCII及其擴充字元集 
作用:表語英語及西歐語言。 
位元:ASCII是用7位表示的,能表示128個字元;其擴充使用8位表示,表示256個字元。 
範圍:ASCII從00到7F,擴充從00到FF。 
ISO-8859-1字元集 
作用:擴充ASCII,表示西歐、希臘語等。 
位元:8位, 
範圍:從00到FF,相容ASCII字元集。 
GB2312字元集 
作用:國家簡體中文字元集,相容ASCII。 
位元:使用2個位元組表示,能表示7445個符號,包括6763個漢字,幾乎覆蓋所有高頻率漢字。 
範圍:高位元組從A1到F7, 低位元組從A1到FE。將高位元組和低位元組分別加上0XA0即可得到編碼。 
BIG5字元集 
作用:統一繁體字編碼。 
位元:使用2個位元組表示,表示13053個漢字。 
範圍:高位元組從A1到F9,低位元組從40到7E,A1到FE。 
GBK字元集 
作用:它是GB2312的擴充,加入對繁體字的支援,相容GB2312。 
位元:使用2個位元組表示,可表示21886個字元。 
範圍:高位元組從81到FE,低位元組從40到FE。 
GB18030字元集 
作用:它解決了中文、日文、朝鮮語等的編碼,相容GBK。 
位元:它採用變位元組表示(1 ASCII,2,4位元組)。可表示27484個文字。 
範圍:1位元組從00到7F; 2位元組高位元組從81到FE,低位元組從40到7E和80到FE;4位元組第一三位元組從81到FE,第二四位元組從30到39。 
UCS字元集 
作用:國際標準 ISO 10646 定義了通用字元集 (Universal Character Set)。它是與UNICODE同類的組織,UCS-2和UNICODE相容。 
位元:它有UCS-2和UCS-4兩種格式,分別是2位元組和4位元組。 
範圍:目前,UCS-4隻是在UCS-2前面加了0×0000。 
UNICODE字元集 
作用:為世界650種語言進行統一編碼,相容ISO-8859-1。 
位元:UNICODE字元集有多個編碼方式,分別是UTF-8,UTF-16和UTF-32。 
2 ,按所表示的文字分類 
語言                                 字元集                                     正式名稱 
英語、西歐語                     ASCII,ISO-8859-1                MBCS 多位元組 
簡體中文                             GB2312                                    MBCS 多位元組 
繁體中文                             BIG5                                         MBCS 多位元組 
簡繁中文                             GBK                                         MBCS 多位元組 
中文、日文及朝鮮語         GB18030                                  MBCS 多位元組 
各國語言                             UNICODE,UCS                    DBCS 寬位元組 
三,編碼 
UTF-8:採用變長位元組 (1 ASCII, 2 希臘字母, 3 漢字, 4 平面符號) 表示,網路傳輸, 即使錯了一個位元組,不影響其他位元組,而雙位元組只要一個錯了,其他也錯了,具體如下: 
如果只有一個位元組則其最高二進位位為0;如果是多位元組,其第一個位元組從最高位開始,連續的二進位位值為1的個數決定了其編碼的位元組數,其餘各位元組均以10開頭。UTF-8最多可用到6個位元組。 
UTF-16:採用2位元組,Unicode中不同部分的字元都同樣基於現有的標準。這是為了便於轉換。從 0×0000到0×007F是ASCII字元,從0×0080到0×00FF是ISO-8859-1對ASCII的擴充。希臘字母表使用從0×0370到 0×03FF 的代碼,斯拉夫語使用從0×0400到0×04FF的代碼,美國使用從0×0530到0×058F的代碼,希伯來語使用從0×0590到0×05FF的代碼。中國、日本和韓國的表意字元(總稱為CJK)佔用了從0×3000到0×9FFF的代碼;由於0×00在c語言及作業系統檔案名稱等中有特殊意義,故很多情況下需要UTF-8編碼儲存文本,去掉這個0×00。舉例如下: 
UTF-16: 0×0080  = 0000 0000 1000 0000 
UTF-8:   0xC280 = 1100 0010 1000 0000 
UTF-32:採用4位元組。 
優缺點 
UTF-8、UTF-16和UTF-32都可以表示有效編碼空間 (U+000000-U+10FFFF) 內的所有Unicode字元。 
使用UTF-8編碼時ASCII字元只佔1個位元組,儲存效率比較高,適用於拉丁字元較多的場合以節省空間的。 
對於大多數非拉丁字元(如中文和日文)來說,UTF-16所需儲存空間最小,每個字元只佔2個位元組。 
Windows NT核心是Unicode(UTF-16),採用UTF-16編碼在調用系統API時無需轉換,處理速度也比較快。 
採用UTF-16和UTF-32會有Big Endian和Little Endian之分,而UTF-8則沒有位元組順序問題,所以UTF-8適合傳輸和通訊。 
UTF-32採用4位元組編碼,一方面處理速度比較快,但另一方面也浪費了大量空間,影響傳輸速度,因而很少使用。 
四,如何判斷字元集 
1,位元組序 
首先說一下位元組序對編碼的影響,位元組序分為Big Endian位元組序和Little Endian位元組序。不同的處理器可能不一樣。所以,傳輸時需要告訴處理器當時的編碼位元組序。對於前者而言,高位位元組存在低地址,低位元組存於高地址;後者相反。例如,0X03AB, 
Big Endian位元組序 
0000: 0 3 
0001: AB 
Little Endian位元組序是 
0000: AB 
0001: 0 3 
2,編碼識別 
UNICODE,根據前幾個位元組可以判斷UNICODE字元集的各種編碼,叫做Byte Order Mask方法BOM: 
UTF-8: EFBBBF (符合UTF-8格式,請看上面。但沒有含義在UCS即UNICODE中) 
UTF-16 Big Endian:FEFF (沒有含義在UCS-2中) 
UTF-16 Little Endian:FFFE (沒有含義在UCS-2中) 
UTF-32 Big Endian:0000FEFF (沒有含義在UCS-4中) 
UTF-32 Little Endian:FFFE0000 (沒有含義在UCS-4中) 
GB2312:高位元組和低位元組的第1位都是1。 
BIG5,GBK&GB18030:高位元組的第1位為1。作業系統有預設的編碼,常為GBK,可以下載別的並升級。
通過判斷高位元組的第1位從而知道是ASCII或者漢字編碼。

Karlson,2009-07-25 13:39:57

 

  1. class CChineseCode  
  2.  
  3. {  
  4.  
  5.   public:  
  6.  
  7.       static void UTF_8ToUnicode(wchar_t* pOut,char *pText);  // 把UTF-8轉換成Unicode  
  8.  
  9.       static void UnicodeToUTF_8(char* pOut,wchar_t* pText);  //Unicode 轉換成UTF-8  
  10.  
  11.       static void UnicodeToGB2312(char* pOut,wchar_t uData);  // 把Unicode 轉換成 GB2312    
  12.  
  13.       static void Gb2312ToUnicode(wchar_t* pOut,char *gbBuffer);// GB2312 轉換成 Unicode  
  14.  
  15.       static void GB2312ToUTF_8(string& pOut,char *pText, int pLen);//GB2312 轉為 UTF-8  
  16.  
  17.       static void UTF_8ToGB2312(string &pOut, char *pText, int pLen);//UTF-8 轉為 GB2312  
  18.  
  19. };  
  20.  
  21.  
  22.  
  23. 類實現  
  24.  
  25.  
  26.  
  27. void CChineseCode::UTF_8ToUnicode(wchar_t* pOut,char *pText)  
  28.  
  29. {  
  30.  
  31.    char* uchar = (char *)pOut;  
  32.  
  33.  
  34.  
  35.    uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);  
  36.  
  37.    uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);  
  38.  
  39.  
  40.  
  41.    return;  
  42.  
  43. }  
  44.  
  45.  
  46.  
  47. void CChineseCode::UnicodeToUTF_8(char* pOut,wchar_t* pText)  
  48.  
  49. {  
  50.  
  51.    // 注意 WCHAR高低字的順序,低位元組在前,高位元組在後  
  52.  
  53.    char* pchar = (char *)pText;  
  54.  
  55.  
  56.  
  57.    pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));  
  58.  
  59.    pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);  
  60.  
  61.    pOut[2] = (0x80 | (pchar[0] & 0x3F));  
  62.  
  63.  
  64.  
  65.    return;  
  66.  
  67. }  
  68.  
  69.  
  70.  
  71. void CChineseCode::UnicodeToGB2312(char* pOut,wchar_t uData)  
  72.  
  73. {  
  74.  
  75.    WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(wchar_t),NULL,NULL);  
  76.  
  77.    return;  
  78.  
  79. }        
  80.  
  81.  
  82.  
  83. void CChineseCode::Gb2312ToUnicode(wchar_t* pOut,char *gbBuffer)  
  84.  
  85. {  
  86.  
  87.    ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);  
  88.  
  89.    return ;  
  90.  
  91. }  
  92.  
  93.  
  94.  
  95. void CChineseCode::GB2312ToUTF_8(string& pOut,char *pText, int pLen)  
  96.  
  97. {  
  98.  
  99.    char buf[4];  
  100.  
  101.    int nLength = pLen* 3;  
  102.  
  103.    char* rst = new char[nLength];  
  104.  
  105.      
  106.  
  107.    memset(buf,0,4);  
  108.  
  109.    memset(rst,0,nLength);  
  110.  
  111.      
  112.  
  113.    int i = 0;  
  114.  
  115.    int j = 0;        
  116.  
  117.    while(i < pLen)  
  118.  
  119.    {  
  120.  
  121.            //如果是英文直接複製就可以  
  122.  
  123.            if( *(pText + i) >= 0)  
  124.  
  125.            {  
  126.  
  127.                    rst[j++] = pText[i++];  
  128.  
  129.            }  
  130.  
  131.            else  
  132.  
  133.            {  
  134.  
  135.                    wchar_t pbuffer;  
  136.  
  137.                    Gb2312ToUnicode(&pbuffer,pText+i);  
  138.  
  139.                      
  140.  
  141.                    UnicodeToUTF_8(buf,&pbuffer);  
  142.  
  143.                      
  144.  
  145.                    unsigned short int tmp = 0;  
  146.  
  147.                    tmp = rst[j] = buf[0];  
  148.  
  149.                    tmp = rst[j+1] = buf[1];  
  150.  
  151.                    tmp = rst[j+2] = buf[2];      
  152.  
  153.                      
  154.  
  155.                    j += 3;  
  156.  
  157.                    i += 2;  
  158.  
  159.            }  
  160.  
  161.    }  
  162.  
  163.    rst[j] = '';  
  164.  
  165.  
  166.  
  167.    //返回結果  
  168.  
  169.    pOut = rst;                
  170.  
  171.    delete []rst;     
  172.  
  173.      
  174.  
  175.    return;  
  176.  
  177. }  
  178.  
  179.  
  180.  
  181. void CChineseCode::UTF_8ToGB2312(string &pOut, char *pText, int pLen)  
  182.  
  183. {  
  184.  
  185.    char * newBuf = new char[pLen];  
  186.  
  187.    char Ctemp[4];  
  188.  
  189.    memset(Ctemp,0,4);  
  190.  
  191.  
  192.  
  193.    int i =0;  
  194.  
  195.    int j = 0;  
  196.  
  197.      
  198.  
  199.    while(i < pLen)  
  200.  
  201.    {  
  202.  
  203.        if(pText > 0)  
  204.  
  205.        {  
  206.  
  207.                newBuf[j++] = pText[i++];                          
  208.  
  209.        }  
  210.  
  211.        else                    
  212.  
  213.        {  
  214.  
  215.                WCHAR Wtemp;  
  216.  
  217.                UTF_8ToUnicode(&Wtemp,pText + i);        
  218.  
  219.                UnicodeToGB2312(Ctemp,Wtemp);                
  220.  
  221.                newBuf[j] = Ctemp[0];  
  222.  
  223.                newBuf[j + 1] = Ctemp[1];    
  224.  
  225.                i += 3;      
  226.  
  227.                j += 2;     
  228.  
  229.        }  
  230.  
  231.    }  
  232.  
  233.    newBuf[j] = '';    
  234.    pOut = newBuf;    
  235.    delete []newBuf;  
  236.    return;    
  237.  
  238. }
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.