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