3月 31

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.
ここに書いた法則、全部表示させて検証したわけではないので悪しからず。。。

Tagged with:
preload preload preload