美文网首页
Unicode码和Emoji表情

Unicode码和Emoji表情

作者: 林大鹏 | 来源:发表于2021-11-01 22:00 被阅读0次

一.ASCII码到Unicode

ASCII码是7位,它将英文字母,数字0-9以及一些标点符号和控制字符映射为0-127这些整型。

由于8位的空间对于各国文字远远不够,因此Unicode码诞生。
起初,Unicode被设计为16位,提供65536个字符的空间。当时人们认为这已经大到足够编码世界上现代文本里所有的文字和字符了。

考虑到历史上的文字和比较少使用到的日本中国汉字,Unicode编码扩展到21位。

二.Unicode编码空间

Unicode的基本元素被称作编码点(Code Point)。编码点通过数字来区分,通常写成16进制的形式再加上前缀"U+",所有编码点组成的集合被称作编码空间(Code Space)

Unicode的编码空间包含1114112个编码点。然而,其中只有128237个编码点(12%的编码空间被赋值),目前,还有很多空间用来增长,同时,Unicode还保留了另外的137468字符作为"自用"空间,这些字符没有标准的含义,可以被个人应用所使用。

为了对编码空间的布局有个了解,把它可视化会比较直观。下面是整个编码空间的布局,一个像素代表一个编码点。使用小方块表示以保证视觉的一致性;每个小方块是16*16=256个编码点,每个大方块是一个面有65536个编码点,总共加起来有17个面板。

面板.png
  • 白色空间表示未使用
  • 蓝色表示已经使用
  • 绿色表示自用区域
  • 小的红色表示代理区

第一个面板被称作(基本多语言面板BMP)。BMP包含现代文本所需的基本所有字符,包括拉丁文、斯拉夫文、希腊文、汉字(中国),日文、朝鲜文、阿拉伯文、希伯来文、梵文(印度)等。这个面板就是最长Unicode设计所占用的空间(16位,65536个字符).后来扩展到现在这个规模,然而,大部分现代字符在BMP的范围内。

第二个面板则包括历史上的文字,比如苏美尔楔形文字和埃及象形文字以及emoji表情.

第三个面板包含了一大块不常用的历史上的汉字字符。

剩下的面板,除了倒数第三个面板中有一小部分被用作格式化字符;倒数两个面板全部保留自用。

为了和以前的ASCII兼容,Unicode128个字符就是ASCII的拷贝.

三. UTF8,UTF16,UTF32

使用频率图.png

这是unicode编码面板中的前三个面板的使用频率图,可以看出使用频率最高的绝大多数分部在BMP内,零散的来自第二三个面板。第二个面板下高频率使用的字符则是部分emoji表情。

为了解决unicode编码占据的内存问题,unicode就有了几个紧凑的编码。

注意
UTF是Unicode Transformation Format的缩写,意为Unicode转换格式
其中,UTF-8是UTF中最常用的转换格式,是UNICODE的一种变长字符编码。

UTF-32

32位整数编码,很少被用来存储,因为太占用内存和存储空间。

UTF-8/UTF-16
这两个编码是可变长编码,分别由8-bit16-bit为一个单元组成,这些方案中下标值较小的编码点占用的字节数也少,会节省不少内存。

1.UTF-8

UTF-8中,每个编码点依据下标值,被存储为14个字节。

越是常用的字符,字节越短,最前面的128个字符,只使用一个字节表示,与ASCII码完全相同。

image.png

UTF8有以下几个好处:

  • 对于很常见的西文字符,采用这种编码方式也不会浪费内存。

  • 由于UTF-8 是基于 8 位的码元的,因此它并不需要关心字节顺序。

  • 任何已经是 ASCII 编码的字符串和文件无需转换就可以被 UTF-8 识别。

  • 大量的广泛使用的编程惯例——比如 NULL 结尾,分隔符(n,t,’,’,”)等——在 UTF-8中也是可用的。

因为这些原因,UTF-8 成为存储和交流 Unicode 文本方面的最佳编码。它也已经是文件格式、网络协议以及 Web API 领域里事实上的标准了。

2.UTF16

UTF-16编码介于UTF-32UTF-8之间,同时结合了定长和变长两种编码方法的特点。

它的编码规则很简单:基本平面的字符占用2个字节,辅助平面的字符占用4个字节。也就是说,UTF-16的编码长度要么是2个字节(U+0000U+FFFF),要么是4个字节(U+010000U+10FFFF)。

于是这里就存在一个问题,当我们遇到两个字符,怎么看出它本身是一个字符,还是需要跟其他两个字节放在一起解读。

我们可以从基本平面看到,从U+D800U+DFFF是一个空段,即这些码点不对应任何字符。因此,这个空段可以用来映射辅助平面的字符。

具体来说,辅助平面的字符位共有2^20个,也就是说,对应这些字符至少需要20个二进制位。UTF-16将这20位拆成两半,前10位映射在U+D800U+DBFF(空间大小2^10),称为高位(H),后10位映射在U+DC00U+DFFF(空间大小2^10),称为低位(L)。这意味着,一个辅助平面的字符,被拆成两个基本平面的字符表示。

所以,当我们遇到两个字节,发现它的码点在U+D800U+DBFF之间,就可以断定,紧跟在后面的两个字节的码点,应该在U+DC00U+DFFF之间,这四个字节必须放在一起解读。

3. UTF-32

UTF-32,将Unicode的每个码点使用4个字节表示,字节内容一一对应码点。比如,码点0就用4个字节的0表示,码点597D就在前面加两个字节的0

U+0000 = 0x0000 0000

U+597D = 0x0000 597D

UTF-32的优点在于,转换规则简单,查找效率高,缺点在于浪费空间,同样内容的英语文本,会比ASCII码大四倍。

这个缺点导致实际上没有人使用这种编码方法。

四.组合字符

Unicode包含一个系统,可以合并多个编码点,动态组合字符。此系统用这种方式增加灵活性,而不引起编码点的巨大组合膨胀。

例如,带重音的字符“Á”会被表示成由两个编码点组成的字符串:U+0041 “A”拉丁大写字母 a加上 U+0301 “◌́”组合尖音符号。这个字符串自动被渲染成单个字符:“Á”

如今,Unicode还包含许多 “预设的” 编码点,每个表示一个被使用过的组合,例如 U+00C1 “Á” 带锐音符的拉丁大写字母AU+1EC7 “ệ”带扬抑符和下点的小写拉丁字母 e

Unicode 中,预设字符和动态组合系统并存。后果就是有多种方法表示同一个字符串——不同编码点序列产生相同用户可感知的字符。例如,我们之前看到的,表示字符 “Á”,我们可以用一个编码点 U+00C1 ,也可以用两个编码点 U+0041U+0301。要解决这个等值字符串的问题,Unicode 定义了几种形式正规化方法。比如NFDNFC

五.字符簇

Unicode包含多种情况,用户认为的一个"字符"事实上底下可能由多个编码点组成。

Unicode使用"字位簇"的概念来表示这种情况,一个由一个或多个编码点组成的字符串构成一个"用户感知的字符"。

部分的emojiunicode长度大于1的本质原因是这些emoji是字符簇。

从这里我们可以知道emoji表情其实是由一个或多个编码点组成的字符串,那我们要怎么判断用户输入的是否为emoji表情,又或者判断一个字符串中是否包含emoji表情呢。

具体详见下一篇:

iOS 输入框如何限制字符长度和emoji

六. 阅读延伸

Unicode与JavaScript详解
从Emoji的限制到Unicode编码

相关文章

网友评论

      本文标题:Unicode码和Emoji表情

      本文链接:https://www.haomeiwen.com/subject/wdyvaltx.html