一般来说要对字符编码格式进行判断就是根据各种编码两个字节的起止范围作判断,如果符合起止范围就认为是某种字符编码。但理论上来说不同的字符编码有可能会采用同样的字节范围,所以这种方法并不能完全把某个双字节字符对应到唯一的一种编码格式上(所以说如果大家都用 utf-8 ,整个世界就清静了)。这种伴随着计算机发展而衍生出来的各种双字节语言字符编码只能是尽量想办法处理,但难有完美解决方案。
CnCharsetChecker.java 源代码:
public
class
CnCharsetChecker
...
{

/**//* Support for Chinese(GB2312) characters */
// #define isgb2312head(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xf7)
// #define isgb2312tail(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xfe)

public static boolean isGB2312( byte head,byte tail )...{
int iHead = head & 0xff;
int iTail = tail & 0xff;
return ((iHead>=0xa1 && iHead<=0xf7 &&
iTail>=0xa1 && iTail<=0xfe) ? true : false);
}

/**//* Support for Chinese(GBK) characters */
// #define isgbkhead(c) (0x81<=(uchar)(c) && (uchar)(c)<=0xfe)
// #define isgbktail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7e)
// || (0x80<=(uchar)(c) && (uchar)(c)<=0xfe))

public static boolean isGBK( byte head,byte tail )...{
int iHead = head & 0xff;
int iTail = tail & 0xff;
return ((iHead>=0x81 && iHead<=0xfe &&
(iTail>=0x40 && iTail<=0x7e ||
iTail>=0x80 && iTail<=0xfe)) ? true : false);
}

/**//* Support for Chinese(BIG5) characters */
// #define isbig5head(c) (0xa1<=(uchar)(c) && (uchar)(c)<=0xf9)
// #define isbig5tail(c) ((0x40<=(uchar)(c) && (uchar)(c)<=0x7e)
// || (0xa1<=(uchar)(c) && (uchar)(c)<=0xfe))

public static boolean isBIG5( byte head,byte tail )...{
int iHead = head & 0xff;
int iTail = tail & 0xff;
return ((iHead>=0xa1 && iHead<=0xf9 &&
(iTail>=0x40 && iTail<=0x7e ||
iTail>=0xa1 && iTail<=0xfe)) ? true : false);
}

public static void main(String[] args)...{
String sGB = "爱";
String sGBK = "愛";
String sBIG5 = "稲";
byte[] sChars = null;
sChars = sGB.getBytes();
System.out.println(sGB+" is "+
CnCharsetChecker.isGB2312(sChars[0],sChars[1])+" for GB2312;"+
CnCharsetChecker.isGBK(sChars[0],sChars[1])+" for GBK,"+
CnCharsetChecker.isBIG5(sChars[0],sChars[1])+" for BIG5");
sChars = sGBK.getBytes();
System.out.println(sGBK+" is "+
CnCharsetChecker.isGB2312(sChars[0],sChars[1])+" for GB2312;"+
CnCharsetChecker.isGBK(sChars[0],sChars[1])+" for GBK,"+
CnCharsetChecker.isBIG5(sChars[0],sChars[1])+" for BIG5");
sChars = sBIG5.getBytes();
System.out.println(sBIG5+" is "+
CnCharsetChecker.isGB2312(sChars[0],sChars[1])+" for GB2312;"+
CnCharsetChecker.isGBK(sChars[0],sChars[1])+" for GBK,"+
CnCharsetChecker.isBIG5(sChars[0],sChars[1])+" for BIG5");
}
}
以上代码依据 MySQL 源代码中对于 GB2312 / GBK / Big5 这几种常见中文编码格式的双字节范围判断改写。你还可以从 MySQL 源码包的 strings/ctype-*.c 系列文件中找到其他语言字符编码的范围定义(当然现在有了 Google Code Search,你不需要去下载整个源码包也可以搜索到所有相关的代码)。