本文介绍一种新的汉字国标(GB)和BIG5编码的识别方法. 即用通过统计编码的方法来识别GB和BIG5文件. 所谓统计编码即取所有汉字编码的平均值, 再利用该平均值 判断是否为GB或BIG5编码.
作者注意到在显示GB的终端上打印BIG5码的文件时, 发现经常出现底区位的字符,如日文假名和其它符号; 而在显示BIG5的终端上打印GB码的文件时, 经常发现 高区位的BIG5编码. 这是因为两种编码范围的差别 导致的.
本方法与传统的词组识别方法,或设置汉字权重的方法 相比, 具有简单, 快速 的特点. 而且文件的汉字数目越多,统计结果就越准确. 作者通过研究认为, 此方法只适用于含汉字较多的文件 识别, 一般应超过80个汉字.
作者还比较了以下三种统计方法:
第一种方法:

第二种方法:

第三种方法:

我们看到第二种方法最好, 其次是第一种方法, 再次是第三种方法. 并且只有当文件的汉字数目多于80时, 此方法才准确! (由于第二位字节对于区分编码较重要, 所以加权第二位字节 ,比如取最终值为[FirstByte + 权重*SecondByte]更合适, 有待研究).
三种方法的识别阈值都为184左右.
如果需要输出编码确认的概率, 此方法还有待更进一步研究. 有意 者请与作者联系.
/*******************************************************
Please feel free to use, modify
or redistribute this program.
********************************************************/
#define SEP_VALUE 184.
#include <stdio.h>
main(int argc, char **argv)
{
FILE *fp;
if(argc == 1)
fp = stdin;
else {
fp = fopen(argv[1], "r");
if(!fp) {
printf("Cannot open file!\n");
exit(0);
}
}
countfile(fp);
fclose(fp);
}
countfile(FILE *fp)
{
int ch1, ch2;
unsigned long int num=0, value=0;
float final;
while((ch1 = fgetc(fp))!=EOF){
if(ch1 & 0x80){
/* value += ch1; num ++;
*/ ch2 = fgetc(fp);
value += ch2; num ++;
}
}
if(num == 0) {
printf("Pure 7-bit character file.\n");
exit(0);
}
if(num < 80)
printf("The result maybe incorrect!\n");
final = (float)value/(float)num;
printf("Average:%.2f .... %s.\n",
final, ((final>SEP_VALUE)? "GB File":"BIG5 File"));
}
|