美文网首页
Emoji表情的拦截

Emoji表情的拦截

作者: Nagi | 来源:发表于2017-12-14 17:08 被阅读90次

start

先看一个编码


编码示例

看到这个Code,如何解析?那就要先谈一谈编码空间了。

  • U+0000~U+10FFFF, 16进制,从U+~U+10共17个,叫平面,每个平面的编码数量自然是16 *16*16*16=65535
  • 第一个平面为基本多语言平面,也叫第零平面,其它的叫辅助平面。
  • 第一个平面中U+D800~U+DFFF是保留的。
    那么,就可以利用这个保留标志位

Emoji编码

emoji编码有2个字节的,也有4个字节的,当然都得大于0xd800,官方规定了高位从0xd800~0xdbff, 低位从0xdc00~0xdfff.

  • 先看看Code如何转化为utf编码吧:
  • 0x1F340, 第一空间,先减去0x10000,得到0x0F340
  • 转化为二进制 0000 1111 0011 0100 0000 一共10位
  • 分成高位和低位,得到 00 0011 1100 和 11 0100 0000,16进制为 0x003C 0x0340
  • 上值加0xd800 :0xd800 + 0x003C = 0xd83C
  • 下值加0xdc00: 0xdc00 + 0x0340 = 0xdf62

过滤

那么,如何过滤?先看看别人是怎么做的吧
http://www.jianshu.com/p/2597d4c3a183
其主要思路就是判断编码的范围
其中一段识别代码,是上面解析编码的逆运算:

const unichar hs = [substring characterAtIndex:0];
if (0xd800 <= hs && hs <= 0xdbff) {
         if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
             if (0x1d000 <= uc && uc <= 0x1f77f) {
                 isEomji = YES;
             }
         }
     }

再附加一些零星的判断

__block BOOL isEomji = NO;
[string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
 ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
     const unichar hs = [substring characterAtIndex:0];
     if (0xd800 <= hs && hs <= 0xdbff) {
         if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
             if (0x1d000 <= uc && uc <= 0x1f77f) {
                 isEomji = YES;
             }
         }
     } else if (substring.length > 1) {
         const unichar ls = [substring characterAtIndex:1];
         if (ls == 0x20e3) {
             isEomji = YES;
         }
     } else {
         if (0x2100 <= hs && hs <= 0x27ff && hs != 0x263b) {
             isEomji = YES;
         } else if (0x2B05 <= hs && hs <= 0x2b07) {
             isEomji = YES;
         } else if (0x2934 <= hs && hs <= 0x2935) {
             isEomji = YES;
         } else if (0x3297 <= hs && hs <= 0x3299) {
             isEomji = YES;
         } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50|| hs == 0x231a ) {
             isEomji = YES;
         }
     }
 }];

因为代码比较老,可能会遗漏,那么顺着思路把编码范围判断补全不就好了?于是找到官网看看

http://unicode.org/emoji/format.html#col-totals
https://apps.timwhitlock.info/emoji/tables/unicode#block-6c-other-additional-symbols

其编码范围比较飘逸,还老新增,要想简单搞一下基本不行,必定漏判、误判。维护也很蛋疼。

提个思路:把官网上编码都爬下来,生成数据库,判断的时候查一下,相当于搞了个字库,这样徒增应用大小了。

再换个思路,其实本来之所以要拦截,还是因为后台数据库默认不支持,并不是从使用上考虑要拦截,因此,还是让数据库取支持emoji的存储比较靠谱。

相关文章

网友评论

      本文标题:Emoji表情的拦截

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