iOS 程序员眼中的 Emoji

作者:Hsusue

链接:https://juejin.im/post/5dc3b9a46fb9a04a95289a84(点击尾部阅读原文前往)

Emoji 简介

绘文字(日语:絵文字/えもじ emoji)是日本在无线通信中所使用的视觉情感符号,绘指图画,文字指的则是字符,可用来代表多种表情,如笑脸表示笑、蛋糕表示食物等。在中国大陆,emoji通常叫做“小黄脸”,或者直称emoji 在NTTDoCoMo的i-mode系统电话系统中,绘文字的尺寸是12x12 像素,在传送时,一个图形有2个字节。Unicode编码为E63E到E757,而在Shift-JIS编码则是从F89F到F9FC。基本的绘文字共有176个符号,在C-HTML4.0的编程语言中,则另增添了76个情感符号。最早由栗田穰崇(Shigetaka Kurita)创作,并在日本网络及手机用户中流行。自苹果公司发布的iOS 5输入法中加入了emoji后,这种表情符号开始席卷全球,目前emoji已被大多数现代计算机系统所兼容的Unicode编码采纳,普遍应用于各种手机短信和社交网络中。

以上引用来自百度百科,提到“一个图形有2个字节,Unicode 编码范围为E63E到E757”。但人的创造性是无穷的,限定的区域无法满足人们表达的欲望。所以 Emoji 并不限定于2个字节,人类针对这个问题制定了越来越多的规则。

但限定的规则总是伴随着两个问题——兼容性以及扩展性,如何过滤掉不支持的 Emoji,如何扩展更多的 Emoji。

核心问题就是 Emoji 编码规则是怎样的。

Emoji 编码

MAC 下查看 Unicode 编码 和 UTF-8 编码

按 ctrl + cmd + 空格,展示 Emoji 键盘,点击右上角。

点击左上角设置 - 自定列表。

选中 Unicode 。

现在我们就可以选中 Emoji 查看 Unicode 和 UTF-8 码。

可以看到这个狗东西,Unicode 书写成 U+1F436,UTF-8 占用了四个字节。

如果你点多几个 Emoji 来看,会发现事情并不简单。

中国国旗占了两个 Unicode代码块,UTF-8 占了八个字节。

gay 里 gay 气的 Emoji UTF-8 居然占了...不想数,Unicode 的代码点(后面会提到这概念) 也不止一个。

更有趣的是,晒黑后字节数也不一样。

那 Unicode 和 UTF-8 是什么呢?要了解这个问题,首先要追溯到 ASCII。

ASCII

ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符。

一个字符的ASCII码占用存储空间为1个字节。所以理论上能表示 2^8 = 256 个字符。

标准ASCII码也叫基础ASCII码,只用到了后7位,即128个字符,剩下最高位(b7)用于校验。

虽然128个足以表示英语中的所有日常字符,但是例如法语注音符号é等就不足以表示,所以一些欧洲国家也用了最高位代表另外的符号。

总的来说,ASCII码 0~127 表示的符号都是一样的,128~255 表示的可能有所差别。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。

至于博大精深的汉语,文字就更多了,1个字节不足以表示所有的汉字,所以 GBK 编码等采用了2个字节。

同理,人的创造性是无穷的,Emoji、花漾字等,所以也诞生了许多别的编码方式,所需的字节数会越来越多。

但无论如何,各种编码方式 0~127 代表的字符都建议与标准 ASCII 码中一样,达到兼容的效果。

Unicode

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。——百度百科

Unicode码:Unicode码是一种国际标准编码,采用二个字节编码,与ASCII码不兼容。——百度百科

可以看到,Unicode 包括字符集、编码方案等;采用两个字节编码。

Unicode 的一些概念

字符集、码点

字符集(unicode)是一张码表,它规定了文字与数字的一一对应关系。

在设计字符集时,首先要决定所需字符的数目,并确定所需字符的清单。根据字符的数目,可以设定整数值的上限,这个整数范围称为编码空间(code space)。在Unicode标准中,编码空间的整数范围是从0到10FFFF(编码空间其中的一个特定整数称为一个码点(code point)),共1,114,112个可用的码点。

然后,为字符清单中的每个字符指定一个整数值,也就是一个码点。这样就得到一个字符集,称作编码字符集(Coded Character Set)。

在书写 Unicode 字符的码位时,通常会在前面加一个前缀 U+,而数值部分会用 4 位到 6 位十六进制数值表示。如字符“A”在 Unicode 中的码位为 U+0041。

平面

Unicode 编码空间的范围为0到10FFFF,可以被划分为字符平面(planes of characters),一共有17个平面,每个平面包含2^16,64K个码点。

  • 平面 0 (U+0000 - U+FFFF) 被称为基本多语言平面 Basic Multilingual Plane (BMP),也称为第零平面, 其中包含了那些频繁使用的字符。

  • 平面 1 (U+10000 - U+1FFFF) 被称为增补多语言平 Supplementary Multilingual plane (SMP),也称为第一平面。其中包含了一些不常使用的字母系统,如 Deseret。

  • 平面 2 (U+20000 - U+2FFFF) 被称为增补表意字符平面 Supplementary Ideographic Plane (SIP),也称为第二平面。其中包含的事表意字符(如汉字),这其中的大多数字符是不常使用的。

  • 平面 14 (U+E0000 - U+EFFFF) 被称为增补专用平面 Supplementary Special-purpose Plane(SSP)。

  • 平面 15 和 16 (U+F0000 - U+10FFFF) 是 Private Use planes。加上 U+E000 - U+F8FF 就构成了 Unicode 的 Private Use Area(PUA)。这部分区域是 Unicode 为用户保留的,Unicode 不会给这些码位指定字符,应用可以在这块区域添加自己的字符。

  • 其它的平面都还没被使用。

Unicode 转换格式:UTFs

UTF是“Unicode Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。

我们应该见过 UTF-8、UTF-16、UTF-32 的编码。它们占用的字节数不是固定的。举个例子。

UTF-8 通常使用一至四个字节为每个字符编码,但最多可用到6个字节。

128 个 ASCII 字符(Unicode 范围由 U+0000 至 U+007F)只需一个字节,带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及马尔代夫语(Unicode 范围由 U+0080 至 U+07FF)需要二个字节,其他基本多文种平面(BMP)中的字符(CJK属于此类-Qieqie注)使用三个字节,其他 Unicode 辅助平面的字符使用四字节编码。

UTF-8的编码规则很简单, 只有两条:

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

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

如下表:

字节数

表达

Unicode 符号范围




1

0xxxxxxx

0000 0000 - 0000 007F

2

110xxxxx 10xxxxxx

0000 0080 - 0000 07FF

3

1110xxxx 10xxxxxx 10xxxxxx

0000 0800 - 0000 FFFF

4

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

0001 0000 - 0010 FFFF

5

111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

0020 0000 - 03FF FFFF

6

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

0400 0000 - 7FFF FFFF

稍微解释一下。

  • UTF-8 1字节用来表示128个 ASCII 字符,所以 Unicode 符号范围位 0 - 7F,即 0 - 127。其他类比。

  • UTF-8中可以用来表示字符编码的实际位数最多有31位,即6字节中所有x的数目。

Unicode 和 UTF-8 的转换

以"严"举例。unicode 为 4E25(1001110 00100101)。

根据上表, 可以发现4E25处在第三行的 范围内(0000 0800 - 0000 FFFF), 因此"严"的UTF-8编码需要三个字节, 即格式是 "1110xxxx 10xxxxxx 10xxxxxx"。

然后, 从"严"的最后一个二进制位开始, 依次从后向前 填入格式中的x, 多出的位补0. 这样就得到了, "11100100 10111000 10100101", 转换成十六进制就是E4B8A5.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值