轉自: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(馬頭) => "\uD83D\uDC34"
- 查Symbola表,我們的目標對象大致是從
- 1F300-1F3FF => "\uD83C\uDF00" - "\uD83C\uDFFF"
- 1F400-1F4FF => "\uD83D\uDC00" - "\uD83D\uDCFF"
- 1F500-1F5FF => "\uD83D\uDD00" - "\uD83D\uDDFF"
- 1F600-1F6FF => "\uD83D\uDE00" - "\uD83D\uDEFF"
- 1F700-1F7FF => "\uD83D\uDF00" - "\uD83D\uDFFF"
編碼知識
Code | UTF-8 | UTF-16 LE | Surrogates |
---|---|---|---|
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 \ trail | DC00 | DC01 | … | DFFF |
---|---|---|---|---|
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 = "a\uD83D\uDE36b\uD83D\uDE36\uD83D\uDE36\uD83D\uDE36\uD83C\uDE3612312\uD83C\uDE36"; 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
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。