http://events.php.gr.jp/events/show/96

はじめに

PHP でバイナリ処理の話をあまり聞かないので、あえてニッチな所を狙って発表させて頂きます。

一応、自己紹介

  • http://d.hatena.ne.jp/yoya/ で、たまに技術ネタを書いてます。
  • 一昨年位まで、数十万ユーザ規模の携帯サイトでアプリ開発をしていました。
    • PHP では主にバイナリ編集をしていました。フレームワークとかビジネスロジックとかよく知りません。
  • 今も、一応 PHP でお仕事してます。

バイナリの定義

  • Wikipedia より
    通常バイナリとテキストは対比して用いられる。
    テキストとはデータの内容すべてを人間が読んで理解できる (human-readable) 表現形式を指し、
    バイナリとはそうでない表現形式を指すことが多い。

なので、本発表では、バイナリファイルの事を、

テキストエディタで開いて読めない文字とか記号が表示されるようなファイル。

という事にしておきます。

バイナリの実例

% hexdump -C aria.gif
00000000  47 49 46 38 39 61 c8 00  96 00 f7 00 00 00 00 00  |GIF89a..........|
00000010  ff ff ff 96 53 58 29 1b  1c e6 b0 b8 b2 69 76 37  |....SX)......iv7|
00000020  26 29 d6 96 a1 cb c6 c7  34 1c 22 48 31 38 2b 21  |&)......4."H18+!|
<略>

GIF ファイルですね。

$ hexdump -C kuriboo4.png
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 00 c0 00 00 00 e0  08 06 00 00 00 55 70 69  |.............Upi|
00000020  31 00 00 00 04 73 42 49  54 08 08 08 08 7c 08 64  |1....sBIT....|.d|
<略>

PNG です。

先頭の4文字を見ると何か分かる事が多いのですが、その後ろにはよく分からないデータが続いてます。 このよく分からないデータを PHP で改変する方法について、今回はお話します。

PHP とバイナリ

PHP の string 型でバイナリ処理が簡単に出来る。というのが 今回、紹介する Tips の肝です。

本当にバイナリ処理できるの?

\0 は?

C言語が典型例ですが、\0 を文字列が終わったマークとして使う処理系も 結構あるので、string型をバイナリデータとして使う場合、途中で切れないか。 特に、C言語出身者は心配になると思います。

  • 簡単に確認
$s = "This is TEST\n";
$s{3} = "\0";
echo strlen($s)."\n";
echo $s;
13
Thi is TEST
  • 確認done

8bitスルー?

  • US-ASCII は 7bit で表現できるので、先頭1bit が特別扱いされたりしない?
$s = ' ';
$s{3} = 'A';
$s{4} = chr(ord('A') | 0x80);
var_dump(bin2hex($s));
string(10) "20202041c1"
  • 8bit スルーです。日本語とかも入れられるし当然ですね。

バイナリを取り込んでそのまま出力

  • でも、細かい事考えなくても、バイナリファイルを入力して、何も変えずに出力して同じデータが生成されれば、OKですよね。
$data = file_get_contents($argv[1]);
echo $data;
% php echo.php saitama.jpg > output.dat
% md5sum saitama.jpg output.dat
06f741dca38937df3702f6759aead28b  saitama.jpg
06f741dca38937df3702f6759aead28b  output.dat
  • 入力をそのまま出力して、同じデータになりました。
  • 後は、この途中でデータを分割したり結合したり、入れ替えたりすれば編集できる事になります。

byte処理

  • さて、まずは byte 処理から。

bit処理

その他Tips

  • PHP の閉じタグ ?> は使わない。?> の後ろに改行やゴミ文字があった場合に、テキストなら最後にゴミが付くだけで大きな問題になりにくいが、バイナリだと致命的。

Reload   Diff   Front page List of pages Search Recent changes Backup Referer   Help   RSS of recent changes