自動検出漢字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. 漢字の判断をいくつか多くする.
判断効率を考慮して、以下のコードを簡単に書いて判断すれば、基本的な効果を達成することができます.
/*
 * 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