メールや掲示板等の文章を見ていると時々「🗿」のような絵文字が出てきますが、これはUnicodeにより定義されています。
 このような絵文字を取り扱うには少々知識が必要なので、この記事を通して必要な知識をお伝えしたいと思います。
 また、絵文字を含む文字列を1文字ずつ切り出すjavaのサンプルコードも作りました。
 
【絵文字の定義と背景】
 絵文字は符号化文字集合「Unicode」で定義されており、Unicodeの文字符号化方式である「UTF-8」「UTF-16」等で使用することができる。
 (「符号化文字集合」とは「文字」と「文字に割り当てた番号」の対応表、「文字符号化方式」とは「文字に割り当てた番号」と「実際にコンピュータが扱う数字」の対応表のことである)
 なお、「UTF-16」は狭義の「Unicode」として呼ばれることもある。
 
 Unicodeは元々1~2バイト文字を定義していたが、世界中の文字を取り扱いたいという要望に応えるために4バイト文字を拡張領域として定義した。
 絵文字は、この拡張領域に含まれる。
 4バイト文字は、「上位サロゲート(2バイト)+下位サロゲート(2文字)」の組み合わせで定義される。
 「上位サロゲート」は0xD800~0xDBFF(1024通り)、「下位サロゲート」は0xDC00~0xDFFF(1024通り)で定義され、何れも2バイト文字では使用しないコードであるため、表現が衝突することはない。
 
 4バイト文字は定義当時は実際に扱われることが少なかったが、日本の携帯の絵文字の普及により一般的に使われるようになり、Webシステム等では無視できない存在となった。
 
【サンプルコード】
・ソースコード(UTF-8で作成)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class Sample {   public static void main(String args[]){     // 変数で直接4バイト文字込みの文字列を定義し表示     String str = "🚅Unicode🌏絵文字で遊んでみよう😮";     System.out.println("変数から取得:"+str);     // 何も考えず1文字ごと文字と文字コードを出力     // 4バイト文字は2文字扱い     for (int i = 0; i < str.length() ; i++) {       int code = (int)str.charAt(i);       String hex = Integer.toHexString(code);       System.out.println         ((i + 1) + "番目の文字:" +          str.charAt(i) + " 16進数:" + hex);     }     // サロゲート文字で4バイト文字を判定     // 正しく1文字ずつ切り出す     String upperSurStart = "d800";     String upperSurEnd = "dbff";     int fourByteMojiCount = 0;     for (int i = 0; i < str.length() ; i++) {       int mojiPos = i+1-fourByteMojiCount;       int code = (int)str.charAt(i);       String hex = Integer.toHexString(code);       String strOneMoji = "";       if (hex.compareTo(upperSurStart)>=0 &&            hex.compareTo(upperSurEnd)<=0) {         strOneMoji = str.substring(i,i+2);         i++;         fourByteMojiCount++;       } else {         strOneMoji = str.substring(i,i+1);       }       System.out.println(mojiPos + "番目の文字:" +                          strOneMoji);     }   } } | 
・出力
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 変数から取得:🚅Unicode🌏絵文字で遊んでみよう😮 1番目の文字:? 16進数:d83d 2番目の文字:? 16進数:de85 3番目の文字:U 16進数:55 4番目の文字:n 16進数:6e 5番目の文字:i 16進数:69 6番目の文字:c 16進数:63 7番目の文字:o 16進数:6f 8番目の文字:d 16進数:64 9番目の文字:e 16進数:65 10番目の文字:? 16進数:d83c 11番目の文字:? 16進数:df0f 12番目の文字:絵 16進数:7d75 13番目の文字:文 16進数:6587 14番目の文字:字 16進数:5b57 15番目の文字:で 16進数:3067 16番目の文字:遊 16進数:904a 17番目の文字:ん 16進数:3093 18番目の文字:で 16進数:3067 19番目の文字:み 16進数:307f 20番目の文字:よ 16進数:3088 21番目の文字:う 16進数:3046 22番目の文字:? 16進数:d83d 23番目の文字:? 16進数:de2e 1番目の文字:🚅 2番目の文字:U 3番目の文字:n 4番目の文字:i 5番目の文字:c 6番目の文字:o 7番目の文字:d 8番目の文字:e 9番目の文字:🌏 10番目の文字:絵 11番目の文字:文 12番目の文字:字 13番目の文字:で 14番目の文字:遊 15番目の文字:ん 16番目の文字:で 17番目の文字:み 18番目の文字:よ 19番目の文字:う 20番目の文字:😮 | 
 文字の16進数表現は奥深いです。
 先日公開したゾーン10進数・パック10進数もそうですが、文字が16進数でどのように表現されているのかを意識しないとコーディングに支障をきたすこともあります。
 新人の時は16進数をあまり意識しておらず、エラーが出てもその理由がわからなかったりして色々苦労しました…。
 
 今後も、文字の16進数表現でお伝えできることがあれば、記事にしていきたいと思います!
 
  
  
  
  

コメント