像‘联通’、‘女’之类的在记事本上会显示乱码。为什么会出现以上现象呢?
首先要了解下字符编码知识:详情http://apps.hi.baidu.com/share/detail/17798660;
其次要了解汉字GB2312编码知识:详情http://baike.baidu.com/view/25492.htm;
简单来讲就是
ANSI是winow系统默认的编码方式,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。
汉字GB2312由两个字节组成,如果它的二进制码与UTF-8两位字节的规则一样,则系统不会只能智能区分是GB2312编码还是UTF-8编码,
默认则会该GBK编码看成UTF-8,比如:女1100010110101110即符合UTF-8编码又符合GB2312编码,系统认为为UTF-8就会出现乱码;
如果保存的字符为"女人",“人”1100100011001011符合GB2312不符合UTF-8,因此就不会出现乱码。
以下是java代码
/**
* 输入在记事本里默认保存有乱码的汉字
* @author hill
*
*/
public class PrintGibberish {
//最小区码
public static final byte MIN_AREA = 16;
//最大区码
public static final byte MAX_AREA = 55;
//最小位码
public static final byte MIN_DIGIT = 1;
//最大位码
public static final byte MAX_DIGIT = 94;
//组成汉字的基数
public static final int BASE = 160;
//出现乱码的正则
public static final String GIBBERISH_REGEX = "110[0-1]{5}10[0-1]{6}";
/**
* GB 2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。
* 01-09区为特殊符号。 16-55区为一级汉字,按拼音排序。 56-87区为二级汉字,按部首/笔画排序。 10-15区及88-94区则未有编码。
* 举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。
*
* 每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。
* “高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上 0xA0)
* 例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节) 0xA1(第二个字节)储存。区位码=区字节+位字节
* (与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1=B0A1)。
* @throws UnsupportedEncodingException
*/
public static void printAllGibberish() throws UnsupportedEncodingException{
//统计乱码的字数
int count = 1;
for(int i = MIN_AREA; i <= MAX_AREA; i++){
//汉字的区字节
byte areaByte = (byte) (i + BASE);
//汉字区的二进制
String areaBinary = Integer.toBinaryString(i + BASE);
for(int j = MIN_DIGIT; j <= MAX_DIGIT; j++){
//汉字的位字节
byte digitByte = (byte) (j + BASE);
//汉字位的二进制
String digitBinary = Integer.toBinaryString(j + BASE);
//汉字的二进制
String chineseCharacterBinary = areaBinary + digitBinary;
//如果不用window自带的记事本比如UltraEdit、Notepad++等:GIBBERISH_REGEX="11[0]{6}10[0-1]{6}"
if(chineseCharacterBinary.matches(GIBBERISH_REGEX)){
byte[] chineseCharacterBytes = {areaByte, digitByte};
//将二进制数字转换为汉字
String chineseCharacter = new String(chineseCharacterBytes, "GB2312");
System.out.print(chineseCharacter + " ");
//每行显示15个汉字
if(count%15 == 0){
System.out.println();
}
count++;
}
}
}
}
public static void main(String[] args) throws UnsupportedEncodingException {
PrintGibberish.printAllGibberish();
}
}