整理字符与unicode转换

基本理论

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。目前6.0版本已经发布。Unicode定义了大到足以代表人类所有可读字符的字符集。Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。
Unicode的实现方式有UTF-8、UTF-16、UTF-32。
UTF-8以字节为单位对Unicode进行编码,对不同范围的字符使用不同长度的编码。
UTF-16编码以16位无符号整数为单位。
UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。 

形如\u1234的unicode应是采取utf-16的实现方式,所以以下encode方法中先将字符用utf-16方式表示,将每8bit放入byte中,然后将byte转为16进制表示,4个16进制符号就表示一个字符的unicode编码了。

其中与0xff的与运算和删除符号表示两个步骤都是必须的。
1,不进行0xff与,然后输出bytesUtf16[n],感觉诧异,byte不就8bit吗,怎么存输出2+个16位符号?后两个符号是需要的,所以有了&操作。后来理解,因为符号引起的前方补位。-的前补1,16制后前全为f,+补0,16制后仍是byte的16制。所以这里需要与0xff,致使只剩下后8位。也就是编码需要的。
2,Unicode标准建议用BOM(Byte Order Mark)来区分字节序,即在传输字节流前,先传输被作为BOM的字符"零宽无中断空格"。这个字符的编码是FEFF,而反过来的FFFE(UTF-16)和FFFE0000(UTF-32)在Unicode中都是未定义的码位,不应该出现在实际传输中,所以又删除符号操作。

实现

//将字符转为unicode
	public static String encode(String str) {
		if (null == str || str.equals(""))
			return "输入字符";
		StringBuffer sb = new StringBuffer();
		try {
						//用16bit数字编码表示一个字符,每8bit用byte表示。
			byte bytesUtf16[] = str.getBytes("UTF-16");
			for (int n = 0; n < bytesUtf16.length; n++) {
				// 截取后面8位,并用16进制表示。
				str = (java.lang.Integer.toHexString(bytesUtf16[n] & 0XFF));
				// 将获得的16进制表示连成串
				sb.append((str.length() == 1) ? ("0" + str) : str);
			}
			// 去除第一个标记字符
			str = sb.toString().toUpperCase().substring(4);
			char[] chs = str.toCharArray();
			str = "";
			for (int i = 0; i < chs.length; i = i + 4) {
				str += "\\u" + chs[i] + chs[i+1] + chs[i+2] + chs[i+3];
			}
		} catch (Exception e) {
			System.out.print(e.getMessage());
			str = "程序出现异常";
		} finally {
			return str;
		}
	}

	//將unicode转为字符
	public static String decode(final String str) {
		if(null == str || str.equals("")){
			return "輸入unicode";
		}
                 //用正则表达式验证
		Pattern p = Pattern.compile("(\\\\u[0-9a-fA-F]{4})+");
		Matcher m = p.matcher(str);
		if(!(m.find() && m.group().equals(str))){
			return "非法格式";
		}
		String[] strs = str.split("u");
		StringBuffer sb = new StringBuffer();
		for (int i = 1; i <= strs.length - 1; i++) {
			sb.append(new Character((char) Integer.parseInt(strs[i].replace("\\", ""), 16)));
		}
		return sb.toString();
	}

测试

    public static void test(String arg) {
        String unicodeResult = encode(arg);
        String decodeResult = decode(unicodeResult);
        System.out.println(arg + " " + unicodeResult + " " + arg.equals(decodeResult));
    }

    public static void main(String[] args) {
        test("Hello World");
        test("你好 世界");
    }
Hello World \u0048\u0065\u006C\u006C\u006F\u0020\u0057\u006F\u0072\u006C\u0064 true
你好 世界 \u4F60\u597D\u0020\u4E16\u754C true

 

 

 

你可能感兴趣的:(整理字符与unicode转换)