javaScript中的Unicode
javaScript中的Unicode
踩坑 在做某个业务的时候,后端童鞋给到的某个字段的值大概都长这样 javascript "\n#\u0008\u0005\u0012\u001f\u0012\u001d\u0005星球大战\u0006:原力觉醒\n\u000f\u0008\u0006\u0012\u000b\u0012\t张学友\n\n\u0008\u0003\u0012\u0006\u0012\u0004Dior\n\u0012\u0008\u0007\u0012\u000e\u0012\u000c英雄联盟"
对于这样的数据,我是拒绝的。对于这些 unicode
,怎么解析呢?它到底是什么?
什么是编码
其实编码原理很简单,在计算中并非直接存储字符(英文、中文等),而是存储这些字符对应的一个数字,这些字符在网络传输的时候,也是传输字符对应的数字,编码就是将字符转化成相应的数字。
ASCII
大学C语言入门课程最先学习的知识,它用了一个字节的7位表示一个字符,比如字符A的ASCII码是65。ASCII码只用了7个bit编码,注定能编码的字符很少,只有128个。
Unicode编码
ASCII编码只能编码128个字符,而中国汉子就有6000 +,这样显然不够的,然后中国推出GBK 编码,用了两个字节来编码。中国编码用了GBK,那其他国家呢?于是为了统一,推出了Unicode编码。在1991年推出了UCS统一编码,实际应用的是USC-2,用了2个字节来编码,能编码65536个字符。JavsScript中的编码就是用的这个编码方式。
编码都是不涉及计算机存储,传输的。但是在遇到两个字节编码的字符的时候,有个系统是大端顺序读取,Windows就是这样,而Mac上是按照小端顺序读取。如果没有个转化格式,那么就乱了,此时UTF(Unicode Transformation Format,简称为UTF)就产生了。因此,UTF-16使用了大端序(Big-Endian,简写为UTF-16 BE)、小端序(Little-Endian,简写为UTF-16 LE)以及BOM(byte order mark)的概念。避免上述情况的出现。
JavaScript中的编码
JavaScript刚创建出来的时候,只有USC-2编码方式可选,所以就一只用了这个编码方式。上文也提到USC-2一开始使用了两个字节来编码,能够编码65536个字符,从0x0 - 0xFFFF,这个也被称为基本平面(BMP-—Basic Multilingual Plane)。但是后来发现这样的Unicode编码也是不够用,扩展了其他补充平面,从0x010000 - 0x10FFFF,共16个。对于补充平面的字符。对于UTF-16编码方式来说,在0x0 - 0xFFFF之间的编码方式直接使用了2个字节,而补充平面使用了4个字节来编码,其中前两个字节范围是0xD800 - 0xDBFF,后两个字节范围是0xDC00 - 0xDFFF。通过下面的方式完成映射:
H = Math.floor((c-0x10000) / 0x400)+0xD800 L = (c – 0x10000) % 0x400 + 0xDC00
USC-2编码的那些坑
var text = "