GBK编码问题

文章链接:http://www.liuschen.com

http://www.qqxiuzi.cn/zh/hanzi-gbk-bianma.php

GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间

全部编码分为三大部分:

  1. 汉字区。包括:
    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。

  2. 图形符号区。包括:
    a. GB 2312 非汉字符号区。即 GBK/1: A1A1-A9FE。其中除 GB 2312 的符号外,还有 10 个小写罗马数字和 GB 12345 增补的符号。计符号 717 个。
    b. GB 13000.1 扩充非汉字区。即 GBK/5: A840-A9A0。BIG-5 非汉字符号、结构符和“〇”排列在此区。计符号 166 个。

  3. 用户自定义区:分为(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;
}
Loading Disqus comments...
Table of Contents