zoukankan      html  css  js  c++  java
  • 特殊字符(包括emoji)梳理和UTF8编码解码原理(转)

    转自:https://www.jianshu.com/p/57c27d67a8a8

    背景知识

    • emoji表情符号,是20世纪90年代由NTT Docomo栗田穣崇(Shigetaka Kurit)创建的,词义来自日语(えもじ,e-moji,moji在日语中的含义是字符)。emoji可以使数字通信做到让人如同面对面交流,避免错误传达信息。
    • 在NTT DoCoMo的i-mode系统电话系统中,绘文字的尺寸是12x12 像素,在传送时,一个图形有2个字节。
    • 自苹果公司发布的iOS 5输入法中加入了emoji后,这种表情符号开始席卷全球,目前emoji已被大多数现代计算机系统所兼容的Unicode编码采纳,普遍应用于各种手机短信和社交网络中。
    • 所谓Emoji就是一种在Unicode位于u1F601-u1F64F区段的字符。这个显然超过了目前常用的UTF-8字符集的编码范围u0000-uFFFF
     
    image2015-11-10 19_6_17.png

     
    image2015-11-10 19_7_21.png

    知识点

    • 在Java里UTF-8,只支持双字节即u0000-uFFFF,emoji(马头) => "uD83DuDC34"
    • 查Symbola表,我们的目标对象大致是从
      • 1F300-1F3FF => "uD83CuDF00" - "uD83CuDFFF"
      • 1F400-1F4FF => "uD83DuDC00" - "uD83DuDCFF"
      • 1F500-1F5FF => "uD83DuDD00" - "uD83DuDDFF"
      • 1F600-1F6FF => "uD83DuDE00" - "uD83DuDEFF"
      • 1F700-1F7FF => "uD83DuDF00" - "uD83DuDFFF"

    编码知识

    CodeUTF-8UTF-16 LESurrogates
    1F7FF F0 9F 9F BF 3D D8 FF DF D83D DFFF

    UTF-16描述

    Unicode的编码空间从U+0000到U+10FFFF,共有1,112,064个码位(code point)可用来映射字符. Unicode的编码空间可以划分为17个平面(plane),每个平面包含216(65,536)个码位。17个平面的码位可表示为从U+xx0000到U+xxFFFF,其中xx表示十六进制值从0016到1016,共计17个平面。第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0)。其他平面称为辅助平面(Supplementary Planes)。基本多语言平面内,从U+D800到U+DFFF之间的码位区段是永久保留不映射到Unicode字符。UTF-16就利用保留下来的0xD800-0xDFFF区段的码位来对辅助平面的字符的码位进行编码。

    UTF-16解码

    lead trailDC00DC01DFFF
    D800 10000 10001 103FF
    D801 10400 10401 107FF
    DBFF 10FC00 10FC01 10FFFF

    示例:

    例如U+10437编码:

    • 0x10437减去0x10000,结果为0x00437,二进制为0000 0000 0100 0011 0111。
    • 分区它的上10位值和下10位值(使用二进制):0000000001 and 0000110111。
    • 添加0xD800到上值,以形成高位:0xD800 + 0x0001 = 0xD801。
    • 添加0xDC00到下值,以形成低位:0xDC00 + 0x0037 = 0xDC37。
    • 下表总结了该转换,以及其它。颜色指示如何从码点位被分布在所述的UTF-16字节。由UTF-16编码过程中加入附加位以黑色显示。
    符号字符普通二进制UTF-16二进制UTF-16 十六进制字符代码UTF-16BE十六进制字节UTF-16LE十六进制字节
    $ U+0024 0000 0000 0010 0100 0000 0000 0010 0100 0024 00 24 24 00
    U+20AC 0010 0000 1010 1100 0010 0000 1010 1100 20AC 20 AC AC 20
      U+10437 0001 0000 0100 0011 0111 1101 1000 0000 0001 1101 1100 0011 0111 D801 DC37 D8 01 DC 37 01 D8 37 DC
      U+24B62 0010 0100 1011 0110 0010 1101 1000 0101 0010 1101 1111 0110 0010 D852 DF62 D8 52 DF 62 52 D8 62 DF

    解决方案

    一 数据库

    • jar包:mysql connector版本高于5.1.13
    • mysql:utf8mb4的最低mysql版本支持版本为5.5.3+
      • 从utf8改至utf8mb4,需要重启mysql
      • 由于RD不应更改mysql配置,所以需要在业务应用处,调用set names utf8mb4,以使数据以utf8mb4编码存储到数据库

    二 过滤

    由于数据库的治本方法建立在有数据存储的所有涉猎系统都得满足上述条件,所以并不是常常满足。由此还需要一个治标的方法。

    public static void main(String[] args) {
        String source = "auD83DuDE36buD83DuDE36uD83DuDE36uD83DuDE36uD83CuDE3612312uD83CuDE36";
        while (true) {
            Integer pos = source.indexOf("uD83D");
            if (pos == -1) {
                pos = source.indexOf("uD83C");
            }
            if (pos != -1) {
                source = source.substring(0, pos) + source.substring(pos + 2);
            } else {
                break;
            }
        }
        System.out.println(source);
    }
    

    参考

    https://zh.wikipedia.org/wiki/UTF-16

    工具

    http://apps.timwhitlock.info/unicode/inspect/hex/1F7FF
    emoji符号汇总地址



    作者:Lane0x
    链接:https://www.jianshu.com/p/57c27d67a8a8
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    web前端的发展态势
    AngularJs 简单入门
    css代码优化篇
    git提交报错:Please make sure you have the correct access rights and the repository exists.
    Activiti工作流框架学习
    遍历map集合的4种方法
    js设置日期、月份增加减少
    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    webservice_rest接口_学习笔记
    相互匹配两个list集合+动态匹配${}参数
  • 原文地址:https://www.cnblogs.com/weizhxa/p/12010890.html
Copyright © 2011-2022 走看看