码迷,mamicode.com
首页 > 其他好文 > 详细

由iPhone emoji牵扯出的UTF-16编码

时间:2014-08-31 20:08:41      阅读:796      评论:0      收藏:0      [点我收藏+]

标签:unicode   utf-16   utf-8   

问题

在iOS中有emoji表情,这个表情很多机器不能正常显示,笔者决心研究一下这个问题。笔者参考了几个地方:

1. 将字符串转化成unicode和utf-8的工具。点击下载

2. 维基百科utf-16 点击打开

3. 笔者博文utf-8的介绍 点击打开

比如,在输入框输入一个emoji 微笑,然后看看它的编码是什么情况:

bubuko.com,布布扣

可以看到Unicode编码是 D83D-DE03。utf-8的编码是F09F-9883.这个不寻常的,下面会介绍!

这里需要注意一下:通常utf-8是1到3个字节的,也就是说在Unicode编码空间的第0个平面上。这里有必要说明一下utf-8的编码规则(更多点击这里)如图所示:

bubuko.com,布布扣

就上面这个表格,我们举个例子:“汉”字的汉来说。它的unicode是0x6C49,utf8是0xE6B189,带入公式,发现是正确的。

我们再看看“微笑”符号的Unicode:D83D-DE03,已经超过了最大的0X10FFFF了,那么它是如何表示的呢???我们根据utf-8:F09F-9883.来反推Unicode对应的数值吧,看看究竟是为什么:

bubuko.com,布布扣

得出的结果是0x1-F603.这个结果跟Unicode:D83D-DE03的值相差太大,所以,中间肯定经过了一些转换步骤,这个转换就是utf-16的代理!!!

UFT-16

    UTF是"Unicode/UCS Transformation Format"的首字母缩写,即把Unicode字符转换为某种格式之意。上面第二张图片展示的是utf-8和unicode的对应表,这只是一个简单的对应,却非常好用。

    在正常情况下一个Unicode两个字节,在转化uft-8的时候,根据协议,两个两个字节,对应一个uft-8这样完成转化或者称为映射!

    其实在第0个平面中,专门有一个代理区域,用于指向第1到第16个平面中的字符,这段区域是:D800——DFFF.。其中0xD800——0xDBFF是前导代理(lead surrogates).0xDC00——0xDFFF是后尾代理(trail surrogates).一个代理对儿(前导,后尾),就表示一个utf-16的字符。就那emoji的微笑来说,前导是代理:D83D;后尾代理是:DE03。根据下图可以得出utf-16的值是:0x1-F603。

    这就照应上了。

bubuko.com,布布扣

作为程序员的,笔者做一个比喻:这对儿(前导代理,后尾代理)就像一个个指针,指向了第1——16平面上的每一个码位。经过计算不难得出:16个平面X每个平面码位65536 = 1,048,576个,前导X后尾也是1,048,576个。这是一个完美的解决方案!!!如上图所示。

这样做的好处是:我们根据Unicode的第一个字节来判断:

if(Unicode第一个字节 >=0xD8 && Unicode <=0xDB){
    //这是代理区域,表示第1——16平面的字符。每四个字节表示一个单元
}
else{
    //这是正常映射区域,表示第0个平面。每两个字节表示一个单元。
}

这样的结果是:根据这个协议,计算机可以知道两个字节,还是四个自己表示一个字符。

总结

这里说的utf-8和utf-16,其实本质上是一样的。只是utf-8是一个直接的映射。而utf-16需要根据代理区的(前导代理,后尾代理)来映射。utf-16比utf-8多了一步而已!

话又说回来:如果不是代理区域的出现,就emoji 微笑的unicode: D83D-DE03来说。计算机甚至不知道这是一个字符,还是两个字符?

由iPhone emoji牵扯出的UTF-16编码

标签:unicode   utf-16   utf-8   

原文地址:http://blog.csdn.net/hherima/article/details/38961575

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!