不要小看小小的 emoji 表情

不要小看小小的 emoji 表情

前言

好久没更新了,最近事比较多,或许下个月就会恢复到正常的发文频次。

这篇文章得从一个 emoji 表情开始,我之前开源的一个 IM 项目中有朋友提到希望可以支持 emoji 表情传输。

https://github.com/crossoverJie/cim/issues/12

不要小看小小的 emoji 表情

正好那段时间有空,加上这功能看着也比较简单准备把它实现了。

但在真正实现时却发现没那么简单。

不要小看小小的 emoji 表情

我首先尝试将一个 emoji 表情存入数据库看看:

不要小看小小的 emoji 表情

果不其然的出错了,导致这个异常的原因是目前数据库所支持的编码中并不能存放 emoji,那 emoji 表情到底是个什么东西呢。

本质上来说计算机所存储的信息都是二进制 01,emoji 也不例外,只要存储和读取(编解码)的方式一致那就可以准确的展示这个信息。

更多编解码的内容后文再介绍,这里先想想如何快速解决问题。

存储 emoji

虽说想要在 MySQL 中存储 emoji 的方式也有好几种,比如可以升级存储字符集到可以存放 emoji ,但这种需要 MySQL 的版本支持。

所以更保险的方式还是在应用层解决,比如我们是否可以将 emoji 当做字符串存储,只是显示的时候要格式化为一个 emoji 表情,这样对于所有的数据库版本都可兼容。

于是我们这里的需求是一个 emoji 表情转换为字符串,同时还得将这个字符串转换为 emoji。

为此我在 GitHub 上找到了一个库,它可以方便的将一个 emoji 转换为字符串的别名,同时也支持将这个别名转换为 emoji。

https://github.com/vdurmont/emoji-java

@Test public void emoji() throws Exception{ String str = "An :grinning:awesome :smiley:string 😄with a few :wink:emojis!"; String result = EmojiParser.parseToUnicode(str); System.out.println(result); result = EmojiParser.parseToAliases(str); System.out.println(result); }

不要小看小小的 emoji 表情

所以基于这个基础库最终实现了表情功能。

不要小看小小的 emoji 表情

其实它本质上是自己维护了一个 emoji 的别名及它的 Unicode 编码(本质上是 UTF-16)的映射关系,再每次格式化数据的时候都会从这个表中进行翻译。

不要小看小小的 emoji 表情

编码知识回顾

自此需求是完成了,但还有几个问题待解决。

Java 中是如何存储 emoji 的?

emoji 是如何进行编码的?

ASCII

在谈 emoji 之前非常有必要了解下计算机编码鼻祖的 ASCII 码。

大家现在都知道在计算机内部存储数据本质上都是二进制的 0/1,对于一个字节来说有 8 位;每一位可以表示两种状态,也就是 0 或 1,这样排列组合下来,一个字节就可以表示 256(2∧8) 种不同的状态。

不要小看小小的 emoji 表情

对于美国来说他们日常使用的英语只需要 26 个英文字母,再加上一些标点符号就足够用计算机来进行信息交流。

于是上个世纪 60年代定义了一套二进制与英文字符的映射关系,可以表明 128 个不同的英文字符,也就是现在的 ASCII 码。

这样我们就可以使用一个字节来表示现代英文,看起来非常不错。

Unicode

随着计算机的发展,逐渐在欧洲、亚洲地区流行;再利用这套 ASCII 码进行信息交流显然是不行的,很多地区压根就不使用英文,而且也远超了 128 位字符(中文就更不用说了)。

虽说一个字节在 ASCII 码中只用了 128 位,但剩下(258-128)的依然不足用用于描述其他语言。

这时如果能有一种包含了世界上所有的文字的字符集,每一个地区的文字都在这个字符集中有唯一的二进制表示,这样便不会出现乱码问题了。

Unicode 就是来做这个的,截止目前 Unicode 已经收录了 10W+ 的字符,你所能使用的字符都包含进去了。

UTF-8

Unicode 虽说包含了几乎所有的文字,但在我们日常使用好像很少看到他的身影,我们用的更多的还是 UTF-8 这样的编码规则。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwfdx.html