Unicode 编码字符集旨在收集全球所有的字符,为每个字符分配唯一的字符编号即代码点(Code Point),用 U+紧跟着十六进制数表示。所有字符按照使用上的频繁度划分为 17 个平面(编号为 0-16),即基本的多语言平面和增补平面。基本的多语言平面(英文为 Basic Multilingual Plane,简称 BMP)又称平面 0,收集了使用最广泛的字符,代码点从 U+0000 到 U+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 编码方法,例如:
- 中文字符串"你好"的 unicode 编码 16 进制表示为:
\u4f60\u597d - 中文字符串"你好"的 unicode 编码 2 进制表示为:
01001111 01100000 01011001 01111101 - 英文字符串"ab"的 unicode 编码 16 进制表示为:
\u0061\u0062 - 英文字符串"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 |