自動検出漢字GB 18030符号化とUTF-8符号化
3101 ワード
まず漢字のGB 18030符号化とUTF-8符号化範囲を見てみましょう
GB18030
第1位:0 x 81~0 xFE 1000,0001~1111 1110
2位:0 x 40~0 x 7 E 0100 0000~0111 1110
または:0 x 80~0 xFE 1000 0000~1111 1110
UTF-8
1位:0 xE 0~0 xEF 1110 0000~1110 1111
2位:0 x 80~0 xBF 1000 0000~1011 1111
3位:0 x 80~0 xBF 1000 0000~1011 1111
漢字を認識するには、次のような特徴が考えられます.
1. 1位が0であれば判断する必要はなく、必ずASCII文字です.
2. 1位が1で始まる場合、2位が0で始まる場合、GBコードに違いありません.
3. 1位が非1110で始まる場合は、必ずGB符号化である.
4. 漢字の判断をいくつか多くする.
判断効率を考慮して、以下のコードを簡単に書いて判断すれば、基本的な効果を達成することができます.
テスト例を書いてテストします.
コンパイル:
実行結果:
参考文献:
UTF-8符号化検出失敗特例
http://www.kuqin.com/language/20071201/2740.html
UTF-8ファイルのUnicode署名BOM(Byte Order Mark)問題
http://blog.csdn.net/thimin/article/details/1724393
UTF-8
http://zh.wikipedia.org/zh-cn/UTF-8
GB 18030
http://zh.wikipedia.org/wiki/GB_18030
ダウンロード:
http://download.csdn.net/detail/firstboy0513/4137551
GB18030
第1位:0 x 81~0 xFE 1000,0001~1111 1110
2位:0 x 40~0 x 7 E 0100 0000~0111 1110
または:0 x 80~0 xFE 1000 0000~1111 1110
UTF-8
1位:0 xE 0~0 xEF 1110 0000~1110 1111
2位:0 x 80~0 xBF 1000 0000~1011 1111
3位:0 x 80~0 xBF 1000 0000~1011 1111
漢字を認識するには、次のような特徴が考えられます.
1. 1位が0であれば判断する必要はなく、必ずASCII文字です.
2. 1位が1で始まる場合、2位が0で始まる場合、GBコードに違いありません.
3. 1位が非1110で始まる場合は、必ずGB符号化である.
4. 漢字の判断をいくつか多くする.
判断効率を考慮して、以下のコードを簡単に書いて判断すれば、基本的な効果を達成することができます.
/*
* Get the character code type. (UTF-8 or GB18030)
* @param s the string to be operator.
* @return return the code type. (1 means UTF-8, 0 for GB18030, -1 for error)
*/
int get_character_code_type(const char* s)
{
if (NULL == s)
{
return -1;
}
int i = 0;
for(; s[i] != '\0'; i++)
{
// ASCII character.
if (!(s[i] & 0x80))
{
continue;
}
// Hanzi utf-8 code possiable.
else if(!( (s[i] & 0xF0) ^ 0xE0)
&& s[i+1]
&& !( (s[i+1] & 0xC0) ^ 0x80)
&& s[i+2]
&& !( (s[i+2] & 0xC0) ^ 0x80))
{
return 1;
}
// Not a UTF-8 code.
else
{
return 0;
}
}
return -1;
}
テスト例を書いてテストします.
#include "char_code.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("%s [file_path]
", argv[0]);
return -1;
}
// open file and read buf.
int f = open(argv[1], O_RDONLY);
if ( -1 == f )
{
fprintf(stderr, "file %s open failed.
", argv[1]);
return -1;
}
char buf[1024] = {0};
read(f, buf, 1023);
int ret = get_character_code_type(buf);
fprintf(stdout, "char code type = %s
", (ret == 1 ? "UTF-8" : "GB18030"));
// close file.
if ( 0 != close(f))
{
fprintf(stderr, "file %s close failed.
", argv[1]);
return -1;
}
return 0;
}
コンパイル:
gcc test.c -o test -O0 -g3 -Wall
実行結果:
$ ./test gb18030.txt
char code type = GB18030
$ ./test utf8.txt
char code type = UTF-8
参考文献:
UTF-8符号化検出失敗特例
http://www.kuqin.com/language/20071201/2740.html
UTF-8ファイルのUnicode署名BOM(Byte Order Mark)問題
http://blog.csdn.net/thimin/article/details/1724393
UTF-8
http://zh.wikipedia.org/zh-cn/UTF-8
GB 18030
http://zh.wikipedia.org/wiki/GB_18030
ダウンロード:
http://download.csdn.net/detail/firstboy0513/4137551