字符编码
字节与位
每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。
编码类型
ASCII
ASCII (American Standard Code for Information Interchange)
unicode
BMP
BMP(Basic Multilingual Plane)字符 Unicode 是目前绝大多数程序使用的字符编码。Unicode 标识符通过一个明确的名字和一个整数来作为它的码点/码位 (code point)。比如,“©️” 字符可以用“版权标志” 和码位 U+00A9 (0xA9,也可以写作十进制 169) 来表示。
码点/码位是为每一个字符提供一个全局唯一的标识符,一个码位映射一个字符,码位值的范围是从U+0000到U+10FFFF,可以表示超过110万个符号。
Unicode 字符分为 17 组平面,每个平面拥有 2^16 (65,536) 个码位。每一个码位都可以用 16 进制 xy0000 到 xyFFFF 来表示,这里的 xy 是表示一个 16 进制的值,从 00 到 10。
而当 xy 是 00 (码点范围是从U+0000到U+FFFF) 的时候,也就是 Unicode 最前 2^16 (65,536) 个字符,被称为基本平面 BMP(Basic Multilingual Plane),最常见的字符都在这个平面上,这也是 Unicode 最先定义和最先公布的一个平面。
其余 16 个平面(U+010000 到 U+10FFFF)称为补充平面(supplementary planes, or astral planes),也称之为补充字符,相对于 BMP 字符而言,这些字符称之为非 BMP 字符。要区分是非 BMP 字符很简单:其码位需要超过 4 位 16 进制表示
非BMP码点
要用两个字节的码点表示非BMP码点,需要用到代理对:
前两个字节称为高位代理或者顶部代理,范围在 0xD800 到 0xDBFF 之间;
后两个字节称为低位代理或者尾部代理,范围在 0xDC00 到 0xDFFF 之间
UTF-8
UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
GBK
GB2312
UCS2
UCS (Universal Coded Character Set)
Javascript 使用ucs-2编码
ES6 对unicode的支持
1. 正确识别字符
ES6可以自动识别4字节的码点
2. 码点表示法
JavaScript允许直接用码点表示Unicode字符,写法是"反斜杠+u+码点"。
3. 字符串处理函数
ES6新增了几个专门处理4字节码点的函数。
String.fromCodePoint():从Unicode码点返回对应字符
String.prototype.codePointAt():从字符返回对应的码点
codePointAt
vs charCodeAt
对于 BMP 字符,charCodeAt 和 codePointAt 的行为一致,都是返回整个字符的码位 (code point);
对于非 BMP 字符,charCodeAt 通过指定参数,返回不同位置上的 code unit 值;而 codePointAt 当参数为 0 时,返回整个字符的码位 (code point),当参数为 1 时,返回的是低位代理 code unit 的值。
反转包含多字节码点的字符串
emoji字符一般是多字节码点。因为js不能识别两个字节以上的码点,因此使用以下方式反转字符串,会错误的截取字符:
这里📦的unicode编码是四字节,split
方法无法正确识别,将一个四字节的字符识别为两个两字节的字符,所以出现了乱码。
可以使用Array.from
方法:
4. 正则表达式
ES6提供了u修饰符,对正则表达式添加4字节码点的支持。
5. 多字节码点字符的长度计算
多字节码点在使用高低位的代理对兼容两字节码点,可以通过正则表达式匹配代理对,匹配出多字节码点字符的长度。
参考资料
Last updated
Was this helpful?