GBK编码问题
http://www.qqxiuzi.cn/zh/hanzi-gbk-bianma.php
GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间
全部编码分为三大部分:
-
汉字区。包括:
a. GB 2312 汉字区。即 GBK/2: B0A1-F7FE。收录 GB 2312 汉字 6763 个,按原顺序排列。
b. GB 13000.1 扩充汉字区。包括:
(1) GBK/3: 8140-A0FE。收录 GB 13000.1 中的 CJK 汉字 6080 个。
(2) GBK/4: AA40-FEA0。收录 CJK 汉字和增补的汉字 8160 个。CJK 汉字在前,按 UCS 代码大小排列;增补的汉字(包括部首和构件)在后,按《康熙字典》的页码/字位排列。
(3) 汉字“〇”安排在图形符号区GBK/5:A996。 -
图形符号区。包括:
a. GB 2312 非汉字符号区。即 GBK/1: A1A1-A9FE。其中除 GB 2312 的符号外,还有 10 个小写罗马数字和 GB 12345 增补的符号。计符号 717 个。
b. GB 13000.1 扩充非汉字区。即 GBK/5: A840-A9A0。BIG-5 非汉字符号、结构符和“〇”排列在此区。计符号 166 个。 -
用户自定义区:分为(1)(2)(3)三个小区。
(1) AAA1-AFFE,码位 564 个。
(2) F8A1-FEFE,码位 658 个。
(3) A140-A7A0,码位 672 个。
第(3)区尽管对用户开放,但限制使用,因为不排除未来在此区域增补新字符的可能性。
其中用户自定义区即表示空白部分,在使用GBK编码时,由于我们一般不改动编码,所以用户自定义区是没有定义的,所以如果要检测半编码的字符,假如字符的编码为ABCD
首先A不能为4,5,6,7,然后就是编码不能在用户定义区的范围内,以下代码是从byte数组中提取60字节来检测是否编码错乱
public static boolean isErrorGBKCode(byte[] bytes){
for (int i = 0; i < 30; i++) {
String hexStringHeader = Integer.toHexString(bytes[i*2]);
String hexStringTail = Integer.toHexString(bytes[i*2+1]);
System.out.println(hexStringHeader+"======="+hexStringTail);
if(hexStringHeader.length()<8 || hexStringTail.length()<8)
continue;
char first = hexStringHeader.charAt(6);
char second = hexStringHeader.charAt(7);
char third = hexStringTail.charAt(6);
char fourth = hexStringTail.charAt(7);
char[] code = {first,second,third,fourth};
String codeStr = new String(code);
/**
* (1) AAA1-AFFE,码位 564 个。
(2) F8A1-FEFE,码位 658 个。
(3) A140-A7A0,码位 672 个。
* */
if(codeStr.matches("^a[a-f][a-f][1-9a-e]$"))
return true;
if(codeStr.matches("^f[8-9a-f][a-f][1-9a-e]$"))
return true;
if(codeStr.matches("^a[1-7][4-9a]0$"))
return true;
if(codeStr.matches("^[^4-7]]"))
return true;
}
return false;
}