判斷一段檔案是UTF-8編碼還是GB2312的編碼方式

來源:互聯網
上載者:User

對於只包含中文和英文的文本中判斷編碼方式是非常簡單的,中文的編碼方式最常用的是GBK,字元集更大的如GBK向下相容GB2312,其中包含的的很多一部分字元是我們在日常生活中用不到的,因此在實際中我們一般只需要區分GB2312和UTF8編碼。這裡我只是提供一種可行的方法,如果判斷GBK也可以採用類似的方式首先分析一下漢字在GB2312中的編碼方式,gb2312規則漢字採用雙位元組編碼其中第一位元組161~247,第二位元組161~254,其中含有邊界條件。而utf8的編碼方式可以看如下表示:


代碼範圍
十六進位
標量值(scalar value)
二進位
UTF-8
二進位/十六進位
注釋
000000 - 00007F
128個代碼
00000000 00000000 0zzzzzzz 0zzzzzzz(00-7F) ASCII字元範圍,位元組由零開始
七個z 七個z
000080 - 0007FF
1920個代碼
00000000 00000yyy yyzzzzzz 110yyyyy(C0-DF) 10zzzzzz(80-BF) 第一個位元組由110開始,接著的位元組由10開始
三個y;二個y;六個z 五個y;六個z
000800 - 00D7FF
00E000 - 00FFFF
61440個代碼 [Note 1]
00000000 xxxxyyyy yyzzzzzz 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz 第一個位元組由1110開始,接著的位元組由10開始
四個x;四個y;二個y;六個z 四個x;六個y;六個z
010000 - 10FFFF
1048576個代碼
000wwwxx xxxxyyyy yyzzzzzz 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz 將由11110開始,接著的位元組由10開始

這樣我們就可以由編碼方式上的差異來進行GB2312和UTF8編碼識別,下面給出代碼

unsigned int countGBK(const char * str){assert(str != NULL);unsigned int len = (unsigned int)strlen (str);    unsigned int counter = 0;    unsigned char head = 0x80;unsigned char firstChar, secondChar;for (unsigned int i = 0; i < len - 1; ++i){firstChar = (unsigned char)str[i];if (!(firstChar & head))continue;secondChar = (unsigned char)str[i];if (firstChar >= 161 && firstChar <= 247 && secondChar>=161 && secondChar <= 254){counter+= 2;++i;}}return counter;}unsigned int countUTF8(const char * str){assert(str != NULL);unsigned int len = (unsigned int)strlen (str);    unsigned int counter = 0;    unsigned char head = 0x80;unsigned char firstChar;for (unsigned int i = 0; i < len; ++i){firstChar = (unsigned char)str[i];if (!(firstChar & head))continue;unsigned char tmpHead = head;unsigned int wordLen = 0 , tPos = 0;while (firstChar & tmpHead){++ wordLen;tmpHead >>= 1;}if (wordLen <= 1)continue; //utf8最小長度為2wordLen --;if (wordLen + i >= len)break;for (tPos = 1; tPos <= wordLen; ++tPos){unsigned char secondChar = (unsigned char)str[i + tPos];if (!(secondChar & head))break;}if (tPos > wordLen){counter += wordLen + 1;i += wordLen;}}return counter;}bool beUtf8(const char *str){    unsigned int iGBK = countGBK(str);unsigned int iUTF8= countUTF8(str);if (iUTF8 > iGBK)return true;return false;}
countUTF8和countGBK分別是為了在文本中數符合UTF8編碼和GB2312編碼方式的字的數量,beUtf8則看哪種編碼方式覆蓋了更多的字元,則認為該文本屬於哪種字元集。注意從編碼方式可以看出有部分GB2312編碼方式和UTF8編碼是衝突的,例如以C0和C1開頭的漢字和UTF8編碼方式重疊,所有if (iUTF8 > iGBK)return true;這個判斷語句有沒有等號則偏向於哪種方式在文本中更常用,如果含有等號,例如在識別“圖片”這個詞時編碼會被誤識別為utf8編碼。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.