字符 char code 与 unicode 编码的关系

Unicode 编码字符集旨在收集全球所有的字符,为每个字符分配唯一的字符编号即代码点(Code Point),用 U+紧跟着十六进制数表示。所有字符按照使用上的频繁度划分为 17 个平面(编号为 0-16),即基本的多语言平面和增补平面。基本的多语言平面(英文为 Basic Multilingual Plane,简称 BMP)又称平面 0,收集了使用最广泛的字符,代码点从 U+0000U+FFFF,每个平面有 65536 个码点;增补平面从平面 1~16,分为增补多语言平面(平面 1)、增补象形平面(平面 2)、保留平面(平 3~13)、增补专用平面等,每个增补平面也有 power(2, 16) = 65536 个码点。所以 17 个平总计有 17 × 65,536 = 1,114,112 个码点。

unicode 目前普遍采用的编码方式是 UCS-2,使用 2 个字节表示有码点的字符,简而言之就是将每一个字符用 16 位 2 进制数标识,但是通常都用 4 位的 16 进制数标识。javascript 语言采用 unicode 字符集,并使用 UCS-2 编码方法,例如:

  1. 中文字符串"你好"的 unicode 编码 16 进制表示为:\u4f60\u597d
  2. 中文字符串"你好"的 unicode 编码 2 进制表示为:01001111 01100000 01011001 01111101
  3. 英文字符串"ab"的 unicode 编码 16 进制表示为:\u0061\u0062
  4. 英文字符串"ab"的 unicode 编码 2 进制表示为:00000000 1100001 00000000 1100010

其中\u是标识 unicode 码用的,后面的 4 位 16 进制数则是对应字符的 unicode 码点。

unicode 编码规则

将一个字符(char)的高 8 位与低 8 位分别取出,转化为 16 进制数,如果转化的 16 进制数的长度不足 2 位则补 0,然后将高、低 8 位转成的 16 进制字符串拼接起来并在前面补上\u即可。

用 java 代码说明 unicode 的编码规则

public class Unicode {    public static void main(String[] args) {        char c = '一'; // 一(4e00)是 unicode 中文字符集首字,龥(9fa5)是 unicode 中文字符集尾字        int i, j;        i = c & 0xFF;        j = c >>> 8;        System.out.println("Original character is: " + c);        System.out.println("low 8 bit is: " + i);        System.out.println("high 8 bit is: " + j);    }}
 javac Unicode.java java UnicodeOriginal character is: 一low 8 bit is: 0high 8 bit is: 78

javascript 版本 console 示例

c = '一'.charCodeAt(0)// 19968i = c & 0xFF // c & 255// 0// 255 的二进制即 11111111,高位前 8 位全为 0,那 2 个数字进行“与”操作之后,高 8 位就被抹去了j = c >>> 8 // 向右移动 8 字节,低位的 8 位就去掉了,只剩下高 8 位了// 78j.toString(16)// "4e"i.toString(16)// "0"

高位78转为 16 进制为4e,将高、低 8 位转成的 16 进制字符串拼接起来即为\u4e00,这就是中文字的 unicode 编码。

在 ajax 请求返回的 responseText 或者 json 数据可以先在服务器端编码为 unicode 格式传给客户端浏览器,这样客户端的页面无论是什么编码,js 都可以很好的处理返回的内容。
4e00的十进制值为4 * 16 * 16 * 16 + 14 * 16 * 16 + 0 * 16 + 0 = 19968

网页中则可以用一来表示中文字,这样不论网页以何种编码,页面始终都可以正常显示,而不会出现乱码。这种方法以前在做 wap 项目常常将页面上所有中文字都用 unicode 编码后发布,就是为了避免乱码问题。

javascript 代码,验证字符串中是否包括中文字

/[\u4e00-\u9fa5]/.test(str)

ruby 中验证字符串中是否包括中文字

/[一-龥]/ =~ str

References

  1. Unicode 介绍
  2. http://haoi77.iteye.com/blog/198840