2009年01月14日
PHPでバイナリデータを解析する場合
どうやってバイナリデータを、計算できる形に持って行くかってはなし。
単なるメモは続きに。
画像などをバイナリデータで読み込んだばあい、そのままだとただのビット列なので扱える形(とりあえず整数)に直さないといけない。 この変換に手間取ったの何のって・・・。
バイナリデータを読み込んだあと、
$file = fopen(FILENAME, 'rb'); flock($file, LOCK_EX); $data = fread($file, 1); // 1バイト(8ビット)読み込む
とりあえずそのまま使ってみたり→化ける。
echo $data;
sprintfを使ってみたり→整数じゃないから変換できない。
echo sprintf("%b", $data); // 2進数として表示→問答無用で0になる echo sprintf("%d", $data); // 10進数として表示→同上 echo sprintf("%c", $data); // 文字として表示→なにも表示されない・・・
整数変換してみたり→だから整数じゃないってば。
echo intval($data); // 整数じゃない echo floatval($data); // 浮動小数点じゃない echo doubleval($data); // 倍精度浮動小数点でもない echo strval($data); // 文字列でもない echo vindec($data); // 2進数でもない
そんなこんなで3時間ほど経ったわけですよ。 途中ニコニコしたりもしてましたが。
答えは結構簡単でした。 今まで「整数からの変換」しか考えてなかったからダメだったわけで。 「ビット列からの変換」を考えればうまくいくわけです。
ビット演算子使って自力で計算してもいいけど、PHPには最初からそんな関数が用意されてます。
echo bin2hex($data);
これで16進数に変換できるので、あとは10進数にするなり32進数にするなり、好きにすればいいわけです。 にしても、数字も文字も、元はビット列のはずなのに、値にかかわらず"0"になったり、なにも表示されなかったりするのはなんでですかね。
09.01.15 17:44追記
コメントにて「ord()」を使えばよいとのアドバイスをいただきました。
次のようにすれば直接10進数の値が取り出せます。
echo ord($data);
データを16進数として使うときはbin2hex()を、10進数として使う場合はord()を使うといいんじゃないでしょうか。
追記ここまで。
あー、もっとうまく検索できるスキルを身につけたい・・・。
クリック動作を無効にするジョークブックマークレット
文字サイズを拡大縮小するスクリプト
ダブルクリックでスクロールするスクリプト
電卓を表示するブックマークレット
ごくごく一部の顔文字を絵文字に置き換えるスクリプト
エントリがあるかと思ったけど、無かったので..._〆(゚▽゚*)
PHPでフォームからのファイルアップロードを処理しましょ。
言語によって微妙に癖が違うからね・・・。
基本事項
P...
試していないけれど、ord($data)で読みだしたデータの整数値が取り出せないかな。もしできればbin2hexよりもordの早いんじゃないかな。
freadで読み込めるのがchar型なら、
echo sprintf("%c", $data);
で対応する文字が表示されるはずなんですが…。
何も表示されないってのは何でなんでしょうね。
ord($data)も試してみました。
見事バイナリデータから10進数の値が取り出せました。
アドバイスありがとうございます。
http://jp.php.net/manual/ja/function.unpack.php