출처 : http://nday.tistory.com/entry/MySQL-51-UTF8에서-iOS5-이모티콘emoji-적용하기
참고 : http://stackoverflow.com/questions/13653712/java-sql-sqlexception-incorrect-string-value-xf0-x9f-x91-xbd-xf0-x9f
http://www.fileformat.info/info/unicode/char/1f47d/index.htm
http://www.fileformat.info/info/unicode/char/1f494/index.htm
http://dev.mysql.com/doc/refman/5.6/en/charset-unicode-utf8mb4.html
1. 개요
이번 iOS가 iOS5로 업데이트되면서 이모티콘이 기본으로 추가되어 사용할 수 있게 되었습니다.
이모티콘을 추가하여 글을 작성하면 Incorrect string value (error code [1366]) 에러가 발생하는데요
원인은 현재 아임IN의 DB는 (MySQL 5.1 UTF-8(3Byte))로 되어 있으며, 추가된 이모티콘은 3Byte 영역을 벗어난 4Byte 영역에 포함되어 있기 때문입니다.
이러한 문제를 기존 프로세스 및 데이터에 영향을 주지 않고 빠르게 해결하기 위해 아래 제시한 방법 중 첫번째 방법을 적용하였습니다.
하지만 첫번째 방법은 새로운 이모티콘이 추가되면 소스코드에 추가된 이모티콘 코드를 추가해줘야 하는 이슈가 있습니다.
따라서 추후 MySQL 5.5 UTF8MB4(4Byte)로 변경하는게 맞다고 생각됩니다.
2. 해결방법
1) iOS5 에서 추가된 SMP영역의 UNICODE를 BMP 영역의 UNICODE로 변환.
- 장점 : Util 추가로 쉽게 적용할 수 있다.
- 단점 : Util을 추가해야 하며, 새로운 이모티콘이 추가될 경우 Util소스코드에 추가하는 작업이 필요하다.
- 참조
변환코드표(SoftBank 코드 사용) : http://unicode.org/~scherer/emoji4unicode/snapshot/utc.html
2) MySQL 5.1 UTF8(3Byte)을 MySQL 5.5 UTF8MB4(4Byte)로 변경.
- 장점 : 5.5로 변경 시 다른 추가 작업이 필요 없다.
- 단점 : 데이터가 많으면 이전 작업 시간이 많이 소요되며, MySQL 5.1과 5.5의 호환성 테스트가 필요하다.
- 참조
MySQL 5.1 UTF8(3Byte) : http://dev.mysql.com/doc/refman/5.1/en/charset-unicode.html
MySQL 5.5 UTF8MB4(4Byte) : http://dev.mysql.com/doc/refman/5.5/en/charset-unicode.html
- MySQL 버전에따른 Unicode 지원 범위 표.
Before MySQL 5.5 | MySQL 5.5 and up |
All Unicode 3.0 characters | All Unicode 5.0 characters |
No supplementary characters | With supplementary characters |
ucs2 character set, BMP only | No change |
utf8 character set for up to three bytes, BMP only | No change |
New utf8mb4 character set for up to four bytes, BMP or supplemental | |
New utf16 character set, BMP or supplemental | |
New utf32 character set, BMP or supplemental |
3) MySQL 5.1 유지하면서 해당 컬럼을 VARBINARY로 변환하고, SELECT 시 CAST(%컬럼명% AS CHAR(사이즈) CHARSET UTF8) 형태로 조회.
- 장점 : MySQL 버전 변경 없이 적용 가능하며, 새로운 이모티콘이 추가되어도 추가작업이 없다.
- 단점 : 조회 SQL구문에 수정이 필요하며, 기존 데이터를 VARBINARY로 변환 시 데이터가 변경될 수 있어 확인이 필요하다.
- 참조
MySQL 5.1 VARBINARY : http://dev.mysql.com/doc/refman/5.1/en/binary-varbinary.html
3. 예제 (iOS5 에서 추가된 SMP영역의 UNICODE를 BMP 영역의 UNICODE로 변환)
package com.paran.test.util; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author 1sec, NDay * * @see http://unicode.org/~scherer/emoji4unicode/snapshot/utc.html * @see http://java.sun.com/developer/technicalArticles/Intl/Supplementary * @see MySQL 5.1 UTF8(3Byte): * http://dev.mysql.com/doc/refman/5.1/en/charset-unicode.html * @see MySQL 5.5 UTF8MB4(4Byte): * http://dev.mysql.com/doc/refman/5.5/en/charset-unicode.html * */ public class EmojiUtil { private static final Log log = LogFactory.getLog(EmojiUtil.class); public static int UNICODE_4_0_EX_START = 0x10000; public static int UNICODE_4_0_EX_END = 0x10FFFF; /* * NOTE * * BMP (Basic Multilingual Plane) * * SMP (Supplementary Multilingual Plane) */ private static int EMOJI_TYPE_BMP_2_CHAR = -1; private static int EMOJI_TYPE_SMP_2_CHAR = -2; private static Map emoji = new HashMap(); private static Map emoji2 = new HashMap(); private static Map emojiSMP2 = new HashMap(); private static Map emojiBMP2 = new HashMap(); /** * SMP to BMP convert Map * */ static { emoji.put(0x1F300, 0xE443); emoji.put(0x1F302, 0xE43C); emoji.put(0x1F303, 0xE44B); emoji.put(0x1F304, 0xE04D); emoji.put(0x1F305, 0xE449); emoji.put(0x1F306, 0xE146); emoji.put(0x1F307, 0xE44A); emoji.put(0x1F308, 0xE44C); emoji.put(0x1F309, 0xE44B); emoji.put(0x1F30A, 0xE43E); emoji.put(0x1F30C, 0xE44B); emoji.put(0x1F314, 0xE04C); emoji.put(0x1F313, 0xE04C); emoji.put(0x1F319, 0xE04C); emoji.put(0x1F31B, 0xE04C); emoji.put(0x1F31F, 0xE335); emoji.put(0x1F550, 0xE024); emoji.put(0x1F551, 0xE025); emoji.put(0x1F552, 0xE026); emoji.put(0x1F553, 0xE027); emoji.put(0x1F554, 0xE028); emoji.put(0x1F555, 0xE029); emoji.put(0x1F556, 0xE02A); emoji.put(0x1F557, 0xE02B); emoji.put(0x1F558, 0xE02C); emoji.put(0x1F559, 0xE02D); emoji.put(0x1F55A, 0xE02E); emoji.put(0x1F55B, 0xE02F); emoji.put(0x1F340, 0xE110); emoji.put(0x1F337, 0xE304); emoji.put(0x1F331, 0xE110); emoji.put(0x1F341, 0xE118); emoji.put(0x1F338, 0xE030); emoji.put(0x1F339, 0xE032); emoji.put(0x1F342, 0xE119); emoji.put(0x1F343, 0xE447); emoji.put(0x1F33A, 0xE303); emoji.put(0x1F33B, 0xE305); emoji.put(0x1F334, 0xE307); emoji.put(0x1F335, 0xE308); emoji.put(0x1F33E, 0xE444); emoji.put(0x1F33C, 0xE305); emoji.put(0x1F33F, 0xE110); emoji.put(0x1F34E, 0xE345); emoji.put(0x1F34A, 0xE346); emoji.put(0x1F353, 0xE347); emoji.put(0x1F349, 0xE348); emoji.put(0x1F345, 0xE349); emoji.put(0x1F346, 0xE34A); emoji.put(0x1F34F, 0xE345); emoji.put(0x1F440, 0xE419); emoji.put(0x1F442, 0xE41B); emoji.put(0x1F443, 0xE41A); emoji.put(0x1F444, 0xE41C); emoji.put(0x1F445, 0xE409); emoji.put(0x1F484, 0xE31C); emoji.put(0x1F485, 0xE31D); emoji.put(0x1F486, 0xE31E); emoji.put(0x1F487, 0xE31F); emoji.put(0x1F488, 0xE320); emoji.put(0x1F466, 0xE001); emoji.put(0x1F467, 0xE002); emoji.put(0x1F468, 0xE004); emoji.put(0x1F469, 0xE005); emoji.put(0x1F46B, 0xE428); emoji.put(0x1F46E, 0xE152); emoji.put(0x1F46F, 0xE429); emoji.put(0x1F471, 0xE515); emoji.put(0x1F472, 0xE516); emoji.put(0x1F473, 0xE517); emoji.put(0x1F474, 0xE518); emoji.put(0x1F475, 0xE519); emoji.put(0x1F476, 0xE51A); emoji.put(0x1F477, 0xE51B); emoji.put(0x1F478, 0xE51C); emoji.put(0x1F47B, 0xE11B); emoji.put(0x1F47C, 0xE04E); emoji.put(0x1F47D, 0xE10C); emoji.put(0x1F47E, 0xE12B); emoji.put(0x1F47F, 0xE11A); emoji.put(0x1F480, 0xE11C); emoji.put(0x1F481, 0xE253); emoji.put(0x1F482, 0xE51E); emoji.put(0x1F483, 0xE51F); emoji.put(0x1F40D, 0xE52D); emoji.put(0x1F40E, 0xE134); emoji.put(0x1F414, 0xE52E); emoji.put(0x1F417, 0xE52F); emoji.put(0x1F42B, 0xE530); emoji.put(0x1F418, 0xE526); emoji.put(0x1F428, 0xE527); emoji.put(0x1F412, 0xE528); emoji.put(0x1F411, 0xE529); emoji.put(0x1F419, 0xE10A); emoji.put(0x1F41A, 0xE441); emoji.put(0x1F41B, 0xE525); emoji.put(0x1F420, 0xE522); emoji.put(0x1F421, 0xE019); emoji.put(0x1F424, 0xE523); emoji.put(0x1F425, 0xE523); emoji.put(0x1F426, 0xE521); emoji.put(0x1F423, 0xE523); emoji.put(0x1F427, 0xE055); emoji.put(0x1F429, 0xE052); emoji.put(0x1F41F, 0xE019); emoji.put(0x1F42C, 0xE520); emoji.put(0x1F42D, 0xE053); emoji.put(0x1F42F, 0xE050); emoji.put(0x1F431, 0xE04F); emoji.put(0x1F433, 0xE054); emoji.put(0x1F434, 0xE01A); emoji.put(0x1F435, 0xE109); emoji.put(0x1F436, 0xE052); emoji.put(0x1F437, 0xE10B); emoji.put(0x1F43B, 0xE051); emoji.put(0x1F439, 0xE524); emoji.put(0x1F43A, 0xE52A); emoji.put(0x1F42E, 0xE52B); emoji.put(0x1F430, 0xE52C); emoji.put(0x1F438, 0xE531); emoji.put(0x1F43E, 0xE536); emoji.put(0x1F43D, 0xE10B); emoji.put(0x1F620, 0xE059); emoji.put(0x1F629, 0xE403); emoji.put(0x1F632, 0xE410); emoji.put(0x1F61E, 0xE058); emoji.put(0x1F635, 0xE406); emoji.put(0x1F630, 0xE40F); emoji.put(0x1F612, 0xE40E); emoji.put(0x1F60D, 0xE106); emoji.put(0x1F624, 0xE404); emoji.put(0x1F61C, 0xE105); emoji.put(0x1F61D, 0xE409); emoji.put(0x1F60B, 0xE056); emoji.put(0x1F618, 0xE418); emoji.put(0x1F61A, 0xE417); emoji.put(0x1F637, 0xE40C); emoji.put(0x1F633, 0xE40D); emoji.put(0x1F603, 0xE057); emoji.put(0x1F606, 0xE40A); emoji.put(0x1F601, 0xE404); emoji.put(0x1F602, 0xE412); emoji.put(0x1F60A, 0xE056); emoji.put(0x1F604, 0xE415); emoji.put(0x1F622, 0xE413); emoji.put(0x1F62D, 0xE411); emoji.put(0x1F628, 0xE40B); emoji.put(0x1F623, 0xE406); emoji.put(0x1F621, 0xE416); emoji.put(0x1F60C, 0xE40A); emoji.put(0x1F616, 0xE407); emoji.put(0x1F614, 0xE403); emoji.put(0x1F631, 0xE107); emoji.put(0x1F62A, 0xE408); emoji.put(0x1F60F, 0xE402); emoji.put(0x1F613, 0xE108); emoji.put(0x1F625, 0xE401); emoji.put(0x1F62B, 0xE406); emoji.put(0x1F609, 0xE405); emoji.put(0x1F63A, 0xE057); emoji.put(0x1F638, 0xE404); emoji.put(0x1F639, 0xE412); emoji.put(0x1F63D, 0xE418); emoji.put(0x1F63B, 0xE106); emoji.put(0x1F63F, 0xE413); emoji.put(0x1F63E, 0xE416); emoji.put(0x1F63C, 0xE404); emoji.put(0x1F640, 0xE403); emoji.put(0x1F645, 0xE423); emoji.put(0x1F646, 0xE424); emoji.put(0x1F647, 0xE426); emoji.put(0x1F64B, 0xE012); emoji.put(0x1F64C, 0xE427); emoji.put(0x1F64D, 0xE403); emoji.put(0x1F64E, 0xE416); emoji.put(0x1F64F, 0xE41D); emoji.put(0x1F3E0, 0xE036); emoji.put(0x1F3E1, 0xE036); emoji.put(0x1F3E2, 0xE038); emoji.put(0x1F3E3, 0xE153); emoji.put(0x1F3E5, 0xE155); emoji.put(0x1F3E6, 0xE14D); emoji.put(0x1F3E7, 0xE154); emoji.put(0x1F3E8, 0xE158); emoji.put(0x1F3E9, 0xE501); emoji.put(0x1F3EA, 0xE156); emoji.put(0x1F3EB, 0xE157); emoji.put(0x1F3EC, 0xE504); emoji.put(0x1F3EF, 0xE505); emoji.put(0x1F3F0, 0xE506); emoji.put(0x1F3ED, 0xE508); emoji.put(0x1F3EE, 0xE30B); emoji.put(0x1F5FB, 0xE03B); emoji.put(0x1F5FC, 0xE509); emoji.put(0x1F5FD, 0xE51D); emoji.put(0x1F45E, 0xE007); emoji.put(0x1F45F, 0xE007); emoji.put(0x1F460, 0xE13E); emoji.put(0x1F461, 0xE31A); emoji.put(0x1F462, 0xE31B); emoji.put(0x1F463, 0xE536); emoji.put(0x1F455, 0xE006); emoji.put(0x1F451, 0xE10E); emoji.put(0x1F454, 0xE302); emoji.put(0x1F452, 0xE318); emoji.put(0x1F457, 0xE319); emoji.put(0x1F458, 0xE321); emoji.put(0x1F459, 0xE322); emoji.put(0x1F45A, 0xE006); emoji.put(0x1F45C, 0xE323); emoji.put(0x1F4B0, 0xE12F); emoji.put(0x1F4B1, 0xE149); emoji.put(0x1F4B9, 0xE14A); emoji.put(0x1F4B2, 0xE12F); emoji.put(0x1F4B5, 0xE12F); emoji.put(0x1F525, 0xE11D); emoji.put(0x1F528, 0xE116); emoji.put(0x1F52B, 0xE113); emoji.put(0x1F52E, 0xE23E); emoji.put(0x1F52F, 0xE23E); emoji.put(0x1F530, 0xE209); emoji.put(0x1F531, 0xE031); emoji.put(0x1F489, 0xE13B); emoji.put(0x1F48A, 0xE30F); emoji.put(0x1F170, 0xE532); emoji.put(0x1F171, 0xE533); emoji.put(0x1F18E, 0xE534); emoji.put(0x1F17E, 0xE535); emoji.put(0x1F380, 0xE314); emoji.put(0x1F381, 0xE112); emoji.put(0x1F382, 0xE34B); emoji.put(0x1F384, 0xE033); emoji.put(0x1F385, 0xE448); emoji.put(0x1F38C, 0xE143); emoji.put(0x1F386, 0xE117); emoji.put(0x1F388, 0xE310); emoji.put(0x1F389, 0xE312); emoji.put(0x1F38D, 0xE436); emoji.put(0x1F38E, 0xE438); emoji.put(0x1F393, 0xE439); emoji.put(0x1F392, 0xE43A); emoji.put(0x1F38F, 0xE43B); emoji.put(0x1F387, 0xE440); emoji.put(0x1F390, 0xE442); emoji.put(0x1F383, 0xE445); emoji.put(0x1F391, 0xE446); emoji.put(0x1F4DE, 0xE009); emoji.put(0x1F4F1, 0xE00A); emoji.put(0x1F4F2, 0xE104); emoji.put(0x1F4DD, 0xE301); emoji.put(0x1F4E0, 0xE00B); emoji.put(0x1F4E8, 0xE103); emoji.put(0x1F4E9, 0xE103); emoji.put(0x1F4EA, 0xE101); emoji.put(0x1F4EB, 0xE101); emoji.put(0x1F4EE, 0xE102); emoji.put(0x1F4E2, 0xE142); emoji.put(0x1F4E3, 0xE317); emoji.put(0x1F4E1, 0xE14B); emoji.put(0x1F4E6, 0xE112); emoji.put(0x1F4E7, 0xE103); emoji.put(0x1F4BA, 0xE11F); emoji.put(0x1F4BB, 0xE00C); emoji.put(0x1F4BC, 0xE11E); emoji.put(0x1F4BD, 0xE316); emoji.put(0x1F4BE, 0xE316); emoji.put(0x1F4BF, 0xE126); emoji.put(0x1F4C0, 0xE127); emoji.put(0x1F4C3, 0xE301); emoji.put(0x1F4C4, 0xE301); emoji.put(0x1F4D3, 0xE148); emoji.put(0x1F4D6, 0xE148); emoji.put(0x1F4D4, 0xE148); emoji.put(0x1F4D5, 0xE148); emoji.put(0x1F4D7, 0xE148); emoji.put(0x1F4D8, 0xE148); emoji.put(0x1F4D9, 0xE148); emoji.put(0x1F4DA, 0xE148); emoji.put(0x1F4CB, 0xE301); emoji.put(0x1F4CA, 0xE14A); emoji.put(0x1F4C8, 0xE14A); emoji.put(0x1F4C7, 0xE148); emoji.put(0x1F4D2, 0xE148); emoji.put(0x1F4D1, 0xE301); emoji.put(0x1F3BE, 0xE015); emoji.put(0x1F3BF, 0xE013); emoji.put(0x1F3C0, 0xE42A); emoji.put(0x1F3C1, 0xE132); emoji.put(0x1F3C3, 0xE115); emoji.put(0x1F3C4, 0xE017); emoji.put(0x1F3C6, 0xE131); emoji.put(0x1F3C8, 0xE42B); emoji.put(0x1F3CA, 0xE42D); emoji.put(0x1F683, 0xE01E); emoji.put(0x1F687, 0xE434); emoji.put(0x1F684, 0xE435); emoji.put(0x1F685, 0xE01F); emoji.put(0x1F697, 0xE01B); emoji.put(0x1F699, 0xE42E); emoji.put(0x1F68C, 0xE159); emoji.put(0x1F68F, 0xE150); emoji.put(0x1F6A2, 0xE202); emoji.put(0x1F689, 0xE039); emoji.put(0x1F680, 0xE10D); emoji.put(0x1F6A4, 0xE135); emoji.put(0x1F695, 0xE15A); emoji.put(0x1F69A, 0xE42F); emoji.put(0x1F692, 0xE430); emoji.put(0x1F691, 0xE431); emoji.put(0x1F693, 0xE432); emoji.put(0x1F17F, 0xE14F); emoji.put(0x1F6A5, 0xE14E); emoji.put(0x1F6A7, 0xE137); emoji.put(0x1F6A8, 0xE432); emoji.put(0x1F3A1, 0xE124); emoji.put(0x1F3A2, 0xE433); emoji.put(0x1F3A3, 0xE019); emoji.put(0x1F3A4, 0xE03C); emoji.put(0x1F3A5, 0xE03D); emoji.put(0x1F3A6, 0xE507); emoji.put(0x1F3A7, 0xE30A); emoji.put(0x1F3A8, 0xE502); emoji.put(0x1F3A9, 0xE503); emoji.put(0x1F3AB, 0xE125); emoji.put(0x1F3AC, 0xE324); emoji.put(0x1F3AD, 0xE503); emoji.put(0x1F004, 0xE12D); emoji.put(0x1F3AF, 0xE130); emoji.put(0x1F3B0, 0xE133); emoji.put(0x1F3B1, 0xE42C); emoji.put(0x1F3B5, 0xE03E); emoji.put(0x1F3B6, 0xE326); emoji.put(0x1F3B7, 0xE040); emoji.put(0x1F3B8, 0xE041); emoji.put(0x1F3BA, 0xE042); emoji.put(0x1F3BC, 0xE326); emoji.put(0x1F4F7, 0xE008); emoji.put(0x1F4F9, 0xE03D); emoji.put(0x1F4FA, 0xE12A); emoji.put(0x1F4FB, 0xE128); emoji.put(0x1F4FC, 0xE129); emoji.put(0x1F48B, 0xE003); emoji.put(0x1F48D, 0xE034); emoji.put(0x1F48E, 0xE035); emoji.put(0x1F48F, 0xE111); emoji.put(0x1F490, 0xE306); emoji.put(0x1F491, 0xE425); emoji.put(0x1F492, 0xE43D); emoji.put(0x1F51E, 0xE207); emoji.put(0x1F4F6, 0xE20B); emoji.put(0x1F4F3, 0xE250); emoji.put(0x1F4F4, 0xE251); emoji.put(0x1F354, 0xE120); emoji.put(0x1F359, 0xE342); emoji.put(0x1F370, 0xE046); emoji.put(0x1F35C, 0xE340); emoji.put(0x1F35E, 0xE339); emoji.put(0x1F373, 0xE147); emoji.put(0x1F366, 0xE33A); emoji.put(0x1F35F, 0xE33B); emoji.put(0x1F361, 0xE33C); emoji.put(0x1F358, 0xE33D); emoji.put(0x1F35A, 0xE33E); emoji.put(0x1F35D, 0xE33F); emoji.put(0x1F35B, 0xE341); emoji.put(0x1F362, 0xE343); emoji.put(0x1F363, 0xE344); emoji.put(0x1F371, 0xE34C); emoji.put(0x1F372, 0xE34D); emoji.put(0x1F367, 0xE43F); emoji.put(0x1F374, 0xE043); emoji.put(0x1F378, 0xE044); emoji.put(0x1F37A, 0xE047); emoji.put(0x1F375, 0xE338); emoji.put(0x1F376, 0xE30B); emoji.put(0x1F377, 0xE044); emoji.put(0x1F37B, 0xE30C); emoji.put(0x1F379, 0xE044); emoji.put(0x1F493, 0xE327); emoji.put(0x1F494, 0xE023); emoji.put(0x1F495, 0xE327); emoji.put(0x1F496, 0xE327); emoji.put(0x1F497, 0xE328); emoji.put(0x1F498, 0xE329); emoji.put(0x1F499, 0xE32A); emoji.put(0x1F49A, 0xE32B); emoji.put(0x1F49B, 0xE32C); emoji.put(0x1F49C, 0xE32D); emoji.put(0x1F49D, 0xE437); emoji.put(0x1F49E, 0xE327); emoji.put(0x1F49F, 0xE204); emoji.put(0x1F6AC, 0xE30E); emoji.put(0x1F6AD, 0xE208); emoji.put(0x1F6B2, 0xE136); emoji.put(0x1F6B6, 0xE201); emoji.put(0x1F6B9, 0xE138); emoji.put(0x1F6BA, 0xE139); emoji.put(0x1F6C0, 0xE13F); emoji.put(0x1F6BB, 0xE151); emoji.put(0x1F6BD, 0xE140); emoji.put(0x1F6BE, 0xE309); emoji.put(0x1F6BC, 0xE13A); emoji.put(0x1F192, 0xE214); emoji.put(0x1F194, 0xE229); emoji.put(0x1F195, 0xE212); emoji.put(0x1F197, 0xE24D); emoji.put(0x1F199, 0xE213); emoji.put(0x1F19A, 0xE12E); emoji.put(0x1F201, 0xE203); emoji.put(0x1F202, 0xE228); emoji.put(0x1F233, 0xE22B); emoji.put(0x1F235, 0xE22A); emoji.put(0x1F236, 0xE215); emoji.put(0x1F21A, 0xE216); emoji.put(0x1F237, 0xE217); emoji.put(0x1F238, 0xE218); emoji.put(0x1F239, 0xE227); emoji.put(0x1F22F, 0xE22C); emoji.put(0x1F23A, 0xE22D); emoji.put(0x1F250, 0xE226); emoji.put(0x1F4A1, 0xE10F); emoji.put(0x1F4A2, 0xE334); emoji.put(0x1F4A3, 0xE311); emoji.put(0x1F4A4, 0xE13C); emoji.put(0x1F4A6, 0xE331); emoji.put(0x1F4A7, 0xE331); emoji.put(0x1F4A8, 0xE330); emoji.put(0x1F4A9, 0xE05A); emoji.put(0x1F4AA, 0xE14C); emoji.put(0x1F4AB, 0xE407); emoji.put(0x1F534, 0xE219); emoji.put(0x1F535, 0xE21A); emoji.put(0x1F532, 0xE21A); emoji.put(0x1F533, 0xE21B); emoji.put(0x1F536, 0xE21B); emoji.put(0x1F537, 0xE21B); emoji.put(0x1F538, 0xE21B); emoji.put(0x1F539, 0xE21B); emoji.put(0x1F50A, 0xE141); emoji.put(0x1F50D, 0xE114); emoji.put(0x1F50E, 0xE114); emoji.put(0x1F512, 0xE144); emoji.put(0x1F513, 0xE145); emoji.put(0x1F50F, 0xE144); emoji.put(0x1F510, 0xE144); emoji.put(0x1F511, 0xE03F); emoji.put(0x1F514, 0xE325); emoji.put(0x1F519, 0xE235); emoji.put(0x1F51D, 0xE24C); emoji.put(0x1F44A, 0xE00D); emoji.put(0x1F44D, 0xE00E); emoji.put(0x1F446, 0xE22E); emoji.put(0x1F447, 0xE22F); emoji.put(0x1F448, 0xE230); emoji.put(0x1F449, 0xE231); emoji.put(0x1F44B, 0xE41E); emoji.put(0x1F44F, 0xE41F); emoji.put(0x1F44C, 0xE420); emoji.put(0x1F44E, 0xE421); emoji.put(0x1F450, 0xE422); // SMILING FACE WITH OPEN MOUTH AND COLD SWEAT emoji.put(0x1F605, EMOJI_TYPE_BMP_2_CHAR); // LOVE LETTER emoji.put(0x1F48C, EMOJI_TYPE_BMP_2_CHAR); // NATIONAL FLAG emoji.put(0x1F1E8, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1E9, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1EA, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1EB, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1EC, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1EE, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1EF, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1F0, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1F7, EMOJI_TYPE_SMP_2_CHAR); emoji.put(0x1F1FA, EMOJI_TYPE_SMP_2_CHAR); // NATIONAL FLAG emojiSMP2.put(0x1F1E8 + "" + 0x1F1F3, 0xE513); emojiSMP2.put(0x1F1E9 + "" + 0x1F1EA, 0xE50E); emojiSMP2.put(0x1F1EA + "" + 0x1F1F8, 0xE511); emojiSMP2.put(0x1F1EB + "" + 0x1F1F7, 0xE50D); emojiSMP2.put(0x1F1EC + "" + 0x1F1E7, 0xE510); emojiSMP2.put(0x1F1EE + "" + 0x1F1F9, 0xE50F); emojiSMP2.put(0x1F1EF + "" + 0x1F1F5, 0xE50B); emojiSMP2.put(0x1F1F0 + "" + 0x1F1F7, 0xE514); emojiSMP2.put(0x1F1F7 + "" + 0x1F1FA, 0xE512); emojiSMP2.put(0x1F1FA + "" + 0x1F1F8, 0xE50C); emojiBMP2.put(0x1F605, new Integer[] { 0xE415, 0xE331 }); emojiBMP2.put(0x1F48C, new Integer[] { 0xE103, 0xE328 }); // no use icon key // emoji3.put(0x1F1E8, ); // emoji3.put(0x1F1E9, ); // emoji3.put(0x1F1EA, ); // emoji3.put(0x1F1EB, ); // emoji3.put(0x1F1EC, ); // emoji3.put(0x1F1EE, ); // emoji3.put(0x1F1EF, ); // emoji3.put(0x1F1F0, ); // emoji3.put(0x1F1F7, ); // emoji3.put(0x1F1FA, ); // emoji3.put(0x0023, ); // emoji3.put(0x0031, ); // emoji3.put(0x0032, ); // emoji3.put(0x0033, ); // emoji3.put(0x0034, ); // emoji3.put(0x0035, ); // emoji3.put(0x0036, ); // emoji3.put(0x0037, ); // emoji3.put(0x0038, ); // emoji3.put(0x0039, ); // emoji3.put(0x0030, ); } public static String toHexString(int org, int padding) { StringBuffer buff = new StringBuffer(); buff.append(Integer.toHexString(org).toUpperCase()); for (int i = buff.length(); i BMP converted string * */ public static String convertSMP2BMP(String org) { StringBuffer buff = new StringBuffer(); if (org != null) { StringBuffer logData = null; if (log.isDebugEnabled()) { logData = new StringBuffer(); } int key = 0, val = 0; int key2 = 0, val2 = 0; Integer val3[] = null; for (int i = 0, size = org.length(); i = UNICODE_4_0_EX_START) && (key = UNICODE_4_0_EX_START) && (key2 <= UNICODE_4_0_EX_END)) { i++; } if (log.isDebugEnabled()) { logData.append(", key2=").append(toHexString(key2)) .append(", val=").append(toHexString(val2)); } buff.append((char) val2); } else if (val == EMOJI_TYPE_BMP_2_CHAR) { // BMP 중 예외 이모티콘, 2개의 문자조합. if ((val3 = emojiBMP2.get(key)) != null) { for (int j = 0, size2 = val3.length; j < size2; j++) { if (log.isDebugEnabled()) { logData.append(", val").append(j).append("=") .append(toHexString(val3[j])); } buff.append((char) ((int) val3[j])); } } } else { if (log.isDebugEnabled()) { logData.append(", val=").append(toHexString(val)); } buff.append((char) val); } if (log.isDebugEnabled()) { log.debug(logData); } } } return buff.toString(); } public static void main(String[] args) throws Exception { // test code String tmp = "1230\u5b66\ud83d\ude30\ud83d\ude25\ud83d\ude31\ud83d\ude05\ud83c\udde8\ud83c\uddf3"; System.out.println("TRACE, EmojiUtil.main(), [" + convertSMP2BMP(tmp) + "]"); } }