CodeIgniterの学習でBBSを作ったら、携帯電話から使ってみたくなりました。DoCoMoはShifJISのバイナリーで送られて来るので、そのShifJISを表すタグにして保存、SoftBank(3G)はUTF8で送られてくるのでUTF8を表すタグにして保存してみました。
例)
DoCoMoから送られた『晴』マーク : [m:do='f89f']
SoftBankから送られた『晴』マーク : [m:sb='ee818a']
PCに表示する際にはそれぞれに用意したGIF画像を呼び出すimgタグに摩り替えるフィルタを通せば簡単に表示できる。
ではその反対はどうだろうか、携帯電話からBBSを見た場合、このままでも最近の機種であればimgタグで表示された絵文字が見れると思うのだが、折角なので(メモリーが少ない機種でも問題がでないように)ネイティブに表示させたいところであります。
ドコモの場合はタグに埋め込まれた「ShiftJIS文字列」をバイナリー変換し文字列に埋め込み送れば携帯側で表示される、ところがソフトバンクはUTF8をバイナリーにパックして送っても表示されないのです。ダンプして調べたら何となく法則性が見えてきたのでメモ。。。
// SoftBank絵文字、UTF8文字表記から機種表示コード変換
function sb_utf2emoji( $utf )
{
$utf = preg_replace('/^ee/i','',$utf);
$byte1 = strval((int)(hexdec($utf)/256));
$byte2 = strval(hexdec($utf)%256);
switch ($byte1)
{
case 0x80: $byte1 -= 0x39; $byte2 -= 0x60; break;
case 0x81: $byte1 -= 0x3A; $byte2 -= 0x20; break;
case 0x84: $byte1 -= 0x3F; $byte2 -= 0x60; break;
case 0x85: $byte1 -= 0x37; $byte2 -= 0x20; break;
case 0x88: $byte1 -= 0x42; $byte2 -= 0x60; break;
case 0x89: $byte1 -= 0x43; $byte2 -= 0x20; break;
case 0x8C: $byte1 -= 0x3D; $byte2 -= 0x60; break;
case 0x8D: $byte1 -= 0x3E; $byte2 -= 0x20; break;
case 0x90: $byte1 -= 0x40; $byte2 -= 0x60; break;
case 0x91: $byte1 -= 0x41; $byte2 -= 0x20; break;
case 0x94: $byte1 -= 0x43; $byte2 -= 0x60; break;
}
return pack("n",0x1b24) . pack("n",$byte1*0x100+$byte2) . pack("c",0x0f);
}
昔NECの日本語OSで使われていた、漢字IN/漢字OUTの形式に似てる。(笑
絵文字開始コード0x1b24、絵文字終了コード0x0f、となっているようです、本来連続した絵文字を送る場合は、[0x1b24]甲乙丙[0x0f]のようにIN/OUTコードで『絵文字コード列』を挟んで送るのが正しい姿だと思いますが、[0x1b24]甲[0x0f][0x1b24]乙[0x0f][0x1b24]丙[0x0f]のように絵文字コードとセットで送っても問題ないようです(当然バイト数は増えますが)。
CIではこんな感じのヘルパーから呼ぶと便利ですね。
// テキストから機種依存コードへ変換
function text2emoji($str = '')
{
$find = array(
"'\[m=do:(.*?)\]'ies",
"'\[m=sb:(.*?)\]'ies"
);
$replace = array(
'pack("n",hexdec("\\1"))',
'sb_utf2emoji("\\1")'
);
return preg_replace($find, $replace, $str);
}
ps.
ここに書いた法則、全部表示させて検証したわけではないので悪しからず。。。
