欢迎关注个人网站:http://www.iamaddy.net/2016/07/emoji-unicode-parser/

前言

这是一个由乱码引发的故事。抱歉我暂时找不到更加惨烈的图,请相信我,还有更目不忍视的画面。请看下图那些框框,那都是些什么鬼!这是要害死强迫症吗?如果同时看到几十个框,简直让人崩溃。

问题来了,这究竟是些什么鬼?

计算机编码

既然是乱码,当然要看编码,那什么是编码呢?我们都知道,计算机本质上不就是01组成的一坨东西在运作着么?01这叫二进制,也就是最基本最底层的编码。

那么大家平常看到的网页也好,APP也好,上面的这些文字符号是怎么表现出来的?当然是根据标记打印出来的,但计算机只能是二进制的存储,并不能真正存ABCD呀,那就要把字母映射为相应的二进制。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。

ASCII码一共规定了128个字符的编码,比如大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。但你美国英文字母少啊,我中文怎么办呢?全世界其他国家的字母其他语言怎么办呢,那就多加一些字节来表示咯。

如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失了,这就是Unicode。Unicode规定了每个符号都有自己的二进制码。标准虽是标准,但各平台实现标准的进度不一啊,有的各自为政,这就有问题了,就像各大浏览器产商,没给我们前端少带来麻烦啊。简单点说,虽然你苹果实现了这个标准可以显示这个符号,但我Android没有,也不知道这个符号表达成啥,所以暂时给个框吧。

因此导致乱码的真正原因:就是各平台间对Unicode标准实现不一致(包括实现的时间先后不同,以及Unicode所代表含义不同)。

编码分析

那框框的Unicode编码到底是什么呢?charCodeAt() (这个方法有局限性,后面说)方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。

" 追求简單的小生活".charCodeAt(0)
// 57614

57614是个十进制数,对应16进制为E10E,Unicode也可以表示为U+E10E。通过这个网站查询得知结果如下:

一头雾水,PRIVATE USE CODEPOINT这是个什么意思呢?幸好下面有wiki的解释:

In Unicode, the Private Use Areas (PUA) are three ranges of code points (U+E000–U+F8FF in the BMP, and in planes 15 and 16) that, by definition, will not be assigned characters by the Unicode Consortium. The code points in these areas can not be considered as standardized characters in Unicode itself. They are intentionally left undefined so that third parties may define their own characters without conflicting with Unicode Consortium assignments. Under the Unicode Stability Policy, the Private Use Areas will remain allocated for that purpose in all future Unicode versions.

咳咳,由于英文水平问题,但我还是勉强翻译下。大意就是:位于BMP的U+E000–U+F8FF编码,和第15以及16平面的区域的编码,Unicode协会表示不会对该区域的编码指定符号,且这些区域编码不是标准符号,故意留下未定义的区域是让第三方自己去玩

那什么又是BMP,第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0)。其他平面称为辅助平面(Supplementary Planes)。最前面的65536个字符位,都在BMP中。

好了,回到前面看,U+E10E这个Unicode刚好落到了(U+E000–U+F8FF)区间内。所以这个字符是因为第三方自定义的。

网上找到了一份表,http://www.easyapns.com/iphone-emoji-alerts 。U+E10E对应符号如下:

那框真的是这个皇冠emoji吗?因为是用户昵称,查一下就知道了

事实证明,确实没错。那么既然是emoji表情,为什么iphone(9.3.1)都不能正常解析?这编码又是怎么被用户输入进去的?

emoji表情

说到emoji,那我们先来扒一扒emoji的历史故事。

emoji表情源于日本,叫做绘(e=图)文字(moji=字符)。

Emoji were initially used by Japanese mobile operators, NTT DoCoMo, au, and SoftBank Mobile (formerly Vodafone).

日本几家公司各自定义了一套标准,用两个字节表示符号,Shift-JIS(日本电脑系统的一种编码)编码是从F89F到F9FC。当然这已经是上世纪的事情了,其中被广泛采用的是SoftBank标准,也称之为SB (SoftBank,这里不是ShaBi的缩写,咳咳)emoji表情。

发展到今天,Unicode协会把emoji表情纳入标准中,但编码范围重新划分了。前面说了,Private Use Areas 是留给第三方用的,不能瞎占用。

在这个网站查到E10E如下信息:

可以初步怀疑是SoftBank的emoji表情。

恰好手中有台旧的华为手机,有一个系统自带的华为输入法,输入法里面有一些跟苹果emoji一样的表情,只不过数量没这么多。下面四个是华为输入法键盘上的表情:

这四个表情在Unicode中的标准编码是:

注意,如果使用charCodeAt方法来获取Unicode编码的时候要注意了,前面我们提到了该方法有缺陷。简单的原因就是JavaScript使用的编码与utf-8不一样导致,这里不展开讲,有兴趣可以看这篇文章。ES6提供了新的接口来获取码点,codePointAt

输入的结果展示如下:

  • iphone6sp 显示框框

  • huawei 显示空白

虽然在两台机器的表现形式不一样,但都是无法正确显示,那我们看下这到底是什么编码。

上面四个编码落入的区域也是在(U+E000–U+F8FF)内,然后根据上面的网站查询,可以确认是来自SoftBank标准的emoji表情了。

所以只要替换这些编码就好了。

解决方案

也就是说SoftBank emoji表情现在的系统基本不支持,因为已经过时了。

但为什么用户还能够输入这些SoftBank emoji呢?原因就在于有些手机输入法(相对古老了)厂商对emoji的实现还是参照SoftBank的标准。

因此把SoftBank emoji编码转换为Unicode标准的就是解决之道。在github上找到了SoftBank与标准emoji Unicode的对应关系。

有两种解决方案:

1、转换为html实体编码

\uE10E -> \u1F451 -> 												

那些年我们踩过的乱码坑相关推荐

  1. Python开发系列课程(10) - 那些年我们踩过的那些坑(上)

    那些年我们踩过的那些坑 坑01 - 整数比较的坑 在 Python 中一切都是对象,整数也是对象,在比较两个整数时有两个运算符==和is,它们的区别是: is比较的是两个整数对象的id值是否相等,也就 ...

  2. 那些年我们踩过的Hive坑

    原文地址:https://blog.csdn.net/sunnyyoona/article/details/51648871 1. 缺少MySQL驱动包 1.1 问题描述 Caused by: org ...

  3. [Hive]那些年我们踩过的Hive坑

    1. 缺少MySQL驱动包 1.1 问题描述 Caused by: org.datanucleus.store.rdbms.connectionpool.DatastoreDriverNotFound ...

  4. 那些年我们踩过的一些坑之 ClickHouse

    摘要:ClickHouse 挺好用的,但是这些坑防不胜防,用过的才懂.本篇文章将持续更新... 内存限制 写数据失败 删除数据 Join 关联默认值 1.group by 使用内存限制 错误信息如下: ...

  5. 那些年我们踩到过的坑(二):3.1 版 MultiThreadedHttpConnectionManager 未releaseConnection导致应用服务器宕机...

    昨天短信服务又宕机了,jstack打出线程信息发现 所有线程池的线程都在wait,栈信息如下: at java.lang.Object.wait(Native Method) - waiting on ...

  6. 那些年我们踩过的坑,SQL 中的空值陷阱!

    那些年我们踩过的坑,SQL 中的空值陷阱! 置顶 不剪发的Tony老师 2019-12-31 07:31:17 6737 收藏 66 分类专栏: SQL 文章标签: sql 空值 mysql orac ...

  7. 安装python爬虫scrapy踩过的那些坑和编程外的思考

    '转载地址:http://www.cnblogs.com/rwxwsblog/p/4557123.html' 这些天应朋友的要求抓取某个论坛帖子的信息,网上搜索了一下开源的爬虫资料,看了许多对于开源爬 ...

  8. Vue2.0配置mint-ui踩过的那些坑

    Vue2.0配置mint-ui踩过的那些坑 最近开发项目的时候逐渐采用vue.js+mint-ui的技术栈,但是昨天开始配置开发环境的时候,遇到了各种报错,即使是按照两家的官方文档配置,也还是会报错, ...

  9. 与webview打交道中踩过的那些坑

    随着HTML5被越来越多的用到web APP的开发当中,webview这一个神器便日渐凸显出重要地位.简要的说,webview能够在移动应用中开辟出一个窗口,在里面显示html页面,css以及js代码 ...

最新文章

  1. oracle fra空间不足,ORACLE 基础解决方案1_扩大FRA区
  2. 一台电脑怎么接两个显示器_电脑数码类目显示器 篇二:11.11抄作业,个人消费级显示器怎么选--20款好价显示器推荐_显示器...
  3. 深入理解分布式消息队列
  4. python apply_async函数_进程池未执行apply_async中添加的函数就直接结束了
  5. javascript 将毫秒值转换为天-小时-分钟-秒钟
  6. 使用Dockerfile构建Nginx,Tomcat,MySQL镜像
  7. C语言 小游戏 电脑大概率获胜,用C语言实现简单的三子棋小游戏
  8. 2018年千锋Java微服务架构视频教程
  9. 关于输入法图标消失 只能输入英文 win10 语言选项 键盘那里显示 输入法仅桌面的解决办法
  10. appium工作原理
  11. 芒果TV广告投放的展现样式!芒果TV广告投放如何收费?
  12. 关于lora和lorawan所涉及的名词解释
  13. Google广告数据分析与优化总结
  14. c语言实现AD采样后FFT算法,实践“玩转FFT算法...任你移植”,正确AD采样及生成函数表...
  15. modem是插在计算机的什么端口,modem是什么 modem和路由器的区别【详解】
  16. c语言中结构体中默认值,C Struct中的缺省值
  17. linux mysql dengl_linux环境搭建(四)--MYSQL
  18. ewb交通灯报告和文件_基于ewb平台的交通灯电路设计.doc
  19. 爬虫日常-selenium登录12306,绕过验证
  20. 【量化课堂】MPT 模型

热门文章

  1. anaconda pycharm_搭建 Python 高效开发环境: Pycharm + Anaconda
  2. 电脑控制手机屏幕软件_手机屏幕如何投屏到电脑
  3. druid mysql 乱码_2017.02.21   Mysql 字符集 乱码 排错过程
  4. bootstrap table中文文档_用Python完成一件小事:自动生成文档报告
  5. MySQL常见的存储引擎的区别?
  6. [Teamcenter 2007 开发实战] 调用web service
  7. 点号“·”的显示 替代 ul li 的功能
  8. JSP自定义标签入门实例
  9. ShardingSphere UI 初步体验
  10. python调用函数怎么错_python调用函数失败是什么原因