本文介绍一种新的汉字国标(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")); } |