Unicode全称应该是unity code ,翻译过来就是统一码。意思嘛,就是统一地球上所有字符的编码。

编码是什么东西呢?就是把一个东西用一个数字来表示(广义上的概念不是这样,但这里可以这么理解)。对字符的编码,就是把一个字符用一个数字来表示。

最常见的是Ascii编码,学过计算机的大概都知道。字符“a”也就是小写的a,用的是数字97表示,字符“1”用的是49表示。完整的Ascii表有256个字符,分别用0-255来表示。

但世界那么大,语言那么多,区区256怎么能表达完世界上所有的字符呢?所以啊,Unicode就是用来统一世界上所有字符的编码方式了。说到底,也就是把255这个最大值,  放大到 111 4112(0x10FFFF = 17 * (2^16))这个最大值。

100多万的数字用来表示地球上的字符,在没有发现外星人之前,应该是够用了的。汉字也就几万而已,拉丁字母都才26个。像中日韩这样有很多字符的语言是不算多的。

在 Unicode 里面,这些数字有一个概念名词——码位。一个码位代表一个唯一的字符。

码位不会用10进制来表示,而是用16进制表示,一般书写某个字符的码位,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。比如,“字”的码位是U+5B57。

Unicode把65536(2^16)作为一个范围的大小,将111 4112分成了17份,这每一份又有一个概念名词,叫平面。一共有17个平面(65536 * 17 = 1114112)。其中第一个平面叫基本多文种平面,BMP(BasicMultilingual Plane),或称第零平面(Plane 0),是Unicode中的第一个编码区段。

在BMP中,U+4e00到U+9fa5是汉字的码位范围,共20902个,这只是汉字的一部分而已。因为这也没办法啊,汉字的数量比一个平面的最大值65536还多。所以在BMP中只编码了一部分常用的汉字而已,其他生僻字,都编码在了其他的平面中。一般场景下,几千个汉字都已经足够使用,所以也不必太纠结。

65536的16进制是0xFFFF,所以用两个字节就可以表示完第一个平面的所有字符了。

这个时候,你是不是以为,在一个文本文件中,如果我们只保存一个字,比如上面提到的“字”,码位是U+5B57。那么这个文件的二进制流就是01011011 01010111了?呵呵,都是大人,我们就不天真了嘛。没这么简单,但也不复杂。

如果直接存储字符的码位,从理论上来说,肯定是可以的,操作也非常方便。但是站在实用的角度来看,这就不行了,因为太浪费空间了。

举个例子,一个文本文件,里面全部都是用英语来表达书写的(写代码的文件不一般都这样嘛),那么这个文件里所有字符的码位都是在0-127之间,Unicode兼容一般的Ascii编码,也就是第一个字节。大写字母A的码位是U+0061。十进制表示的码位为127的那个字符的十六进制码位为U+00FF。

看到没有,前面始终有两个0,因此,每存储一个字符,都会白白浪费一个字节的空间,因为每个字符的二进制都是00000000XXXXXXXX啊。如果去掉前面这些0,一个文本文件就能减少一半的存储空间,多么美好的事。如果不去掉0,在这个倡导节约型社会的时代,我们难道不觉得可耻吗?

所以呢,我们还需要对码位再次进行编码。。。。别晕,确实是再次编码。但和上面的编码概念是不一样,上面可以看成是对字符集的编码方式。而接下来要说的,是对码位的编码方式,他们的方式是完全不同的。

对字符集的,是将某个字符编码对应到某个数字;

而对码位的,是将码位数值编码对应到某个二进制串。

看到这里千万要挺下去,因为这里懂了后,一切都明朗了。

Unicode是将字符编码到码位,而UTF-8、UTF-16或UTF-32等是将码位编码到二进制串。UTF全称是Unicode Transformation Format,也就是Unicode转换方式。

还是汉字字符“字”,码位是U+5B57。

如果采用UTF-32编码方式,那么二进制串是“00000000 00000000 01011011 01010111”,采用了4个字节,32位二进制来表示了,所以是UTF-32。

也就是说UTF-32的编码规则就是直接把码位转换成2进制存储,简单又粗暴。

如果采用现在最通用的编码方式UTF-8,那么“字”的二进制串是“11100101 10101101 10010111”。只用了三个字节,24位二进制就表示了。

这里怎么不是采用8位二进制来表示了?骚年,不要这么推理嘛。谁说这个8就代表只用8位二进制来表示了。为什么叫8呢,我也不是太清楚,得问提出这种方法的人了。

而对于UTF-16的方式,不同的就是编码方式不一样,所以出来的二进制串也不一样。

先说说UTF-8是按照什么样的规则来编码的吧。最大的特点就是不同范围的码位,用不同的二进制规则来编码。也就是变长的编码方式。

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)

——————–+———————————————

00000000 - 0000007F | 0xxxxxxx

00000080 - 000007FF | 110xxxxx 10xxxxxx

00000800 - 0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx

00010000 - 0010FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8的编码规则简单到只有二条:

1)对于单字节的码位,字节的第一位设为0,后面7位为这个符号的Unicode码位。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个字符的Unicode码位的二进制。

如果觉得16进制的码位范围不太好理解,可以换成10进制的。

码位为0 - 127之间的字符,就编码为1个字节。字节的首位定为0,当程序读到这个字节时,发现第一位是0,就知道这个字符是1个字节编码的。

码位为128 – 2048之间的字符,编码为2个字节。

码位为2049 至 65536之间的字符,编码为3个字节。

码位为65537 至 2097152(但注意码位最大值是1114112)之间的字符,编码为4个字节。

如何计算这些界限值?在编码的几个字节中,剩余的x的个数为n的话,界限值就是2的n次方。

再来聊聊UTF-16的编码方式吧。

和UTF-8类似,也是分了范围。不同码位范围,用不同的编码方式。但只有两个范围:

1.  码位在第一个平面内的字符,直接将码位转换为2个字节的二进制串,储存起来。比如,还是字符“字”,就直接就直接将码位U+5B57,转换成01011011 01010111 储存起来,一共有两个字节。

2.  不是在第一个平面内的,也就是在其他16个平面内的字符,先将码位转换为20位二进制。然后依次放进1101 10XX XXXX XXXX 1101 10XX XXXX XXXX这里面的X中。二进制规律也简单,四个字节分成前后两段,每段都以1101 10开头,其他的都是用来填充的二进制位了。比如,某个字符的码位是U+12345,转换成20位二进制就是0001 0010 0011 0100 0101,用UTF-16编码,出来就是1101 1000 0100 1000 1101 10110100 0101 ,一共有四个字节。

对于第一个范围的规则,很简单的将码位转换为二进制而已,不必多说。

但是,对于第二种方式,有些同学就有疑问了。计算机怎么知道是两个字节解释成一个字符,还是四个字节一起解释成字符呢?

难道是以2个字节,是否以1101 10开头来判断的?但是这个形式开头的二进制串,不会解释成第一个平面内的字符吗?

还真的是这样子的。以1101 10开头的两个字节形成的二进制串,不会被解释成第一个平面内的字符。因为在Unicode里,1101 1000 0000 0000到1101 1011 1111 1111之间(也就是码位U+D800到U+DBFF之间),没有编码任何的字符,这区间是一个空段(其实空段的区间是U+D800到DFFF,这只是其中一部分)。

UTF-16就利用了这个特点,将其他16个平面内的字符就这样编码了。

最终规则就是,字符根据Unicode规则,编码成码位,然后码位根据UTF-8、UTF-16、UTF-32等规则,编码成二进制串。最终存储的,就是这个二进制串了。

今天,在学习 Node.js 中的 Buffer 对象时,注意到它的 alloc 和 from 方法会默认用 UTF-8 编码 ,在数组中每位对应 1 字节的十六进制数。想到了之间学习 ES6 时关于 字符 串的 Unicode 表示法,突然就很想知道 UTF-16 是如何进行 编码 的,我尝试将一些汉字转换成二进制数,然后简单的按 2 个字节一组转换成十六进制,发现对于那些码点较大的汉字,结果 Unicode 编码 则是采用双字节16位来进行编号,可编65536 字符 ,基本上包含了世界上所有的语言 字符 ,它也就成为了全世界一种通用的 编码 ,而且用十六进制4位表示一个 编码 ,非常简结直观,为大多数开发者所接受,特别是十六进制 编码 后,可以解决汉字在js再 编码 过程中出现乱码问题,提高解释速度,我们建议在js脚本中使用十六进制 unicode 编码 。 UniCode 汉字转换,网上很多,但相对比较好使的比较少,... Unicode 编码 详解(一): Unicode 简介及其分类 若觉得本文写得还可以,请多多关注本人所作书籍《C++语法详解》电子工业出版社出版,网盘地址: https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg 本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇) 一、基本知识 1、 Unicode Unicode 又称为统一码、万国码、单一码,是国际组织制定的旨在容纳全球所有 字符 的 编码 方案,包括 字符 集、 编码 方案等,它为每种语言中的每个 字符 设定了统一且唯一的二 <br /> Unicode 目前普遍采用的是UCS-2,它用两个字节来 编码 一个 字符 ,  <br />比如汉字"经"的 编码 是0x7ECF,注意 字符 编码 一般用十六进制来  <br />表示,为了与十进制区分,十六进制以0x开头,0x7ECF转换成十进制  <br />就是32463,UCS-2用两个字节来 编码 字符 ,两个字节就是16位二进制,  <br />2的16次方等于65536,所以UCS-2最多能 编码 65536个 字符 。  <br /> 编码 从0到127的 字符 与ASCII 编码 的 字符 一样,比如字母"a"的Uni 1. 字符 集:要想在计算机中显示文字,必须把文字都收集起来放在一个表中,这个表叫 字符 集(Charset)。 2.码表: 字符 集中的每个文字,都分配一个数字码,这叫码表(Code chart)。比如中文 ‘霸’字,在码表中对应的码是38712(十进制),或者9738(十六进制)。 3. 编码 方式:有了码表,就需要确定哪些文字用几个字节表示,以及如果有多个字节代表一个字,字节的读取顺序,这些就是 字符 编码 方式(Encoding)。 虽然为了严谨起见,上面我把 字符 集和码表分开说明,但实际上很多 字符 集也给 1.什么是 Unicode ? Unicode 的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS,也叫统一码、万国码、单一码。 Unicode 是为了解决传统的 字符 编码 方案的局限而产生的,它为每种语言中的每个 字符 设定了统一并且唯一的二进制 编码 ,以满足跨语言、跨平台进行文本转换、处理的要求。 现在用的一般都是UCS-2,即2个字节 编码 ,而UCS-4是为了防止将来2个字节不够用才开发的。 2.为什么使用 Unicode ? (1)为了不同语 Unicode 是ASCII(美国信息交换标准码) 字符 编码 的一个扩展。ASCII中每个 字符 用7位表示,计算机上每个 字符 8位。 Unicode 使用全16为 字符 编码 ,因此 Unicode 能表示世界上所有能用于计算机通讯的符号。 Unicode 最初是作为ASCII的补充。ASCII最终有26个小写/大写字母、10个数字、32个符号、33个控制代码和一个空格,共128个代码。 大小写 字符 的代码是连续的 大小写字母可以通过改变一位数据相互转换 为了兼容不同国家的语言,需要考虑如何确认和ASCII的兼容。因 Unicode 只有一个 字符 集,中、日、韩的三种文字占用了 Unicode 中0x3000到0x9FFF的部分 Unicode 目前普遍采用的是UCS-2,它用两个字节来 编码 一个 字符 , 比如汉字"经"的 编码 是0x7ECF,注意 字符 编码 一般用十六进制来 表示,为了与十进制区分,十六进制以0x开头,0x7ECF转换成十进制 就是32463,UCS-2用两个字节来编 1.几种常见的数据结构  这里主要总结下小匹夫在工作中常碰到的几种数据结构:Array,ArrayList,List,LinkedList,Queue,Stack,Dictionary 数组Array:   数组是最简单的数据结构。其具有如下特点: 数组存储在连续的内存上。 数组的内容都是相同类型。 Unicode 是一种重要的交互和显示的通用 字符 编码 标准,它覆盖了美国、欧洲、中东、非洲、印度、亚洲和太平洋的语言,以及古文和专业符号。 Unicode 允许交换、处理和显示多语言文本以及公用的专业和数学符号。它希望能够解决多语言的计算,如不同国家的 字符 标准,但并不是所有的现代或古文都能够获得支持。 Unicode 字符 可以适用于所有已知的 编码 。 Unicode 是继 ASCII(美国国家交互信息标准 1.综述简单来说: Unicode 是「 字符 集」UTF-8 是「 编码 规则」其中: 字符 集:为每一个「 字符 」分配一个唯一的 ID(学名为码位 / 码点 / Code Point) 编码 规则:将「码位」转换为字节序列的规则( 编码 /解码 可以理解为 加密/解密 的过程)广义的 Unicode 是一个标准,定义了一个 字符 集以及一系列的 编码 规则,即 Unicode 字符 集和 UTF-8、UTF-16、UTF-32