Unicode编码
最初的unicode编码是固定长度的,16位,也就是2两个字节代表一个字符,这样一共可以表示65536个字符。显然,这样要表示各种语言中所有的字符是远远不够的。Unicode4.0规范考虑到了这种情况,定义了一组附加字符编码,附加字符编码采用2个16位来表示,这样最多可以定义1048576个附加字符。所以4个字节表示一个字符。
Unicode只是一个编码规范,目前实际实现的unicode编码有:UTF-8,UTF-16等。utf-8是考虑了字符是怎么存储在计算机上。
UTF-8
utf-8是一种可变长的编码方式,使用1~6个字节表示一个符号,根据不同的符号调整字节数量。
//ascii字符 1个字节 // byte[] bytes = "a".getBytes("utf-8"); // System.out.println(bytes.length); //1//希腊文2个字节 // byte[] bytes = "α".getBytes("utf-8"); // System.out.println(bytes.length); //2//中文3个字节 // byte[] bytes = "中".getBytes("utf-8"); // System.out.println(bytes.length); //3//中文4个字节(ckj中韩日扩展表意字符) // byte[] bytes = "?".getBytes("utf-8"); // System.out.println(bytes.length); //4
utf-8的可变长字节编码
这是种比较巧妙的设计,如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
以"严"的编码字节数组为例,二进制表示为11100100 10111000 10100101
第一个字节开头有三个连续的1,表示该字符占用三个字节
byte[] bytes = "严".getBytes("utf-8"); //得到utf-8编码StringBuffer sb = new StringBuffer();for(int i =0 ;i) {sb.append(Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1));if(i != bytes.length - 1) {sb.append(" ");}}System.out.println(sb.toString()); //11100100 10111000 10100101
字符a的二进制编码是 01100001 , 开头是0,表示该字节单独表示一个字符
byte[] bytes = "a".getBytes("utf-8");StringBuffer sb = new StringBuffer();for(int i =0 ;i) {sb.append(Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1));if(i != bytes.length - 1) {sb.append(" ");}}System.out.println(sb.toString()); //01100001