[PHP] バイナリデータの扱いとテキストデータとの総互換性

2016年5月7日

PHP テクノロジー プログラミング

バイナリデータが扱えると、デジタルデータの操作幅が広がります。 ちなみに、以下の様なデータフォーマットは仕様が公開されているので、扱う事が可能になると考えても問題ありません。
IMAGEデータ(JPEG , GIF , PNG , BMP....) SOUNDデータ(AIFF , WAV , MP3...) MOVIEデータ(mov , mpeg , mp4...) Applicationデータ(SWF , IFO , xls...)

WEBアプリ構築の可能性

通常の場合であれば、上記のような拡張子、フォーマットに対応したアプリケーションでデータ操作を行う必要があるのですが、バイナリ操作ができるのであれば、好きな環境で好きなデータをコントロールする事が可能になります。 もちろん、バイナリエディタを使って直接コントロールしてもいいのですが、WEBシステムでデータ操作ができる仕組みを作っておくことで、高価なアプリケーションを購入すること無く、WEBアプリケーションを構築する事が可能になるという事なんですね。 PhotoShopはプロ仕様の画像修正ソフトですが、GIMPの様なフリーソフトから、WebアプリのPixlrなどのように、独自仕様でのデータ操作も可能になります。 もちろん、PhotoShopはAdobe社の画像技術であるフィルタやピクセルコントロール、データ縮小アルゴリズムなどが秀逸である事が、使い勝手が非常にいいので、効果な値段を支払う価値はあるので、プロの人は是非そちらをお使いください。

PHPでバイナリを扱う方法

WEBプログラムでバイナリを操作できる事で簡単にWEBアプリが構築できるようになるので、今回はPHPで操作することにします。 PHPのCLIを利用して簡単に利用しましょう。その際に必要なコマンドをメモしておきます。 ちなみに、下記サンプルコードの使い方はそれぞれのヘッダに書いてあるsampleを参照ください。

バイナリデータを読み込んで16進数で表示する(先頭3バイト分)

多くのデータフォーマットが先頭の3バイト程度をデータ・フォーマットの識別子を埋め込んでいます。 下記のコードでそれを取得できます。 この箇所は、テキストで書き込まれている事がほとんどなので、あえてバイナリデータの読み込みをそのまま表示しています。 <?php /** * view 3byte charactor * * --[sample]-- * php view3Charactor.php [target-file] **/ //データファイルの読み込み $data = file_get_contents($argv[1]); //最初の3バイトを取得 for($i=0;$i<3;$i++){ echo substr($data,$i,1); } echo PHP_EOL;

特定箇所を16進数で表示する

バイナリは上記のサンプルのようにテキストではなく、コードで書かれていることが多く、テキストエディタでは、そのコードを文字コードに置き換えて表示しようとしますが、対象の文字コードが存在しない場合は、表示ができない為、文字化けをしたり、2バイト文字のように隣のコードと連動するような場合は、意図しない文字が表示されます。 それを回避するために、コードを数値にして視覚的に表示するようにできますが、バイナリは全ての段落をつなげているコードの集合体なので、数値だと1桁もあれば3桁もあるため、配列がガタガタになり、アドレスが理解しづらくなるため、16進数で表示するのが一般的です。 という事で、16進数の表示ができるようにしてみます。 開始アドレスとそこから取得するバイト数を指定することで、16進数の表示ができます。 <?php /** * view 3byte charactor * * --[sample]-- * php view6bit.php [target-file(string)] [from-byte(int)] [count-bytes(int)] **/ //データファイルの読み込み $data = file_get_contents($argv[1]); //最初の3バイトを取得 $bites = array(); for($i=$argv[2];$i<$argv[3];$i++){ $bytes[] = dechex(ord(substr($data,$i,1))); } echo join(",",$bytes); echo PHP_EOL;

バイナリデータを16進数表示のテキストファイルに書き出し

先ほど取得した16進数データを一度テキストファイルに書き出して、再度バイナリデータとして出力することができれば、テキストデータで内容を修正して元データの修正を行うことが可能になります。 /** * binary to text (output-data) * * --[sample]-- * php bin2txt.php [in-file(string)] * output-file : output.txt **/ //INデータファイルの読み込み $inData = file_get_contents($argv[1]); //バイナリを16進数に変換して出力データの作成 $lineData = array(); $outData = ""; $byteNum = 0; for($i=0;$i<strlen($inData);$i++){ //データを1byteずつ16進数に変換する $data = unpack("H2",substr($inData,$i,1)); $outData .= $data[1]; //バイトカウント $byteNum++; //8byteずつで改行 if($byteNum >= 8){ $byteNum = 0; $outData .= PHP_EOL; } else{ $outData .= ","; } } //データをテキストファイルに書き出す file_put_contents("output.txt",$outData); 下記箇所は、unpackでなく、sprintfでも同じ結果が得られます。 -- unpack("H2",substr($inData,$i,1)); -- sprintf("%02x",ord(substr($inData,$i,1))); --

テキストで書かれた16進数をバイナリファイルとして書き出す

16進数の並びのテキストデータは、SDKを熟読してフォーマットを理解できないと、データとしてはNGになるので、データの書き換えは各フォーマットに従ってください。 ここでは、一度テキスト化したものを再度バイナリ化する事を目的とします。 <?php /** * text to binary * * --[sample]-- * php txt2bin.php [out-file(string)] * input-file : output.txt **/ //16進数で書き込まれたテキストファイルの読み込み(改行区切り) $inData = explode("\n",file_get_contents("output.txt")); //テキストの16進数をバイナリデータに変換 $binData = ""; for($i=0; $i<count($inData); $i++){ if($inData[$i]===""){continue;} $lineData = explode(",",$inData[$i]); for($j=0; $j<count($lineData); $j++){ if($lineData[$j]===""){continue;} $binData.= pack("c",hexdec($lineData[$j])); } } //データをテキストファイルに書き出す file_put_contents($argv[1], $binData);

バイナリデータの扱いで気をつけること

バイナリの扱いは慣れると楽なのですが、なれないと苦痛でしかありません。 進数変換や、言語でのビット移動の扱いなど、通常のインタプリタ言語では気にしないことを行うので当然ですが、必要最低限は、各種WEBサイトや参考書などで勉強するようにしましょう。視野が広がりますよ。
10進数:255(0開始) 16進数:FF 2進数:11111111(2^8) バイナリ記述:0xFF
1byteは8bitという事ですが、今回はbyteの扱いのみを行いました。 各種SDKではbit単位での仕様も書かれているため、こちらも制御できるようにしなければいけません。 ただ、扱いが膨大になるので、bit制御は次回に制御プログラムを構築したいと思います。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ