Presentation is loading. Please wait.

Presentation is loading. Please wait.

PHP でバイナリプログラミン グ 2010/05/11 よや

Similar presentations


Presentation on theme: "PHP でバイナリプログラミン グ 2010/05/11 よや"— Presentation transcript:

1 PHP でバイナリプログラミン グ 2010/05/11 よや http://d.hatena.ne.jp/yoya/

2 はじめに PHP でバイナリ処理の話をあまり聞かない ので、あえてニッチを狙って ( 多分、 PHP 勉強会らしくない ) 発表をさせて頂きます。 キーワード : Binary 、 Format, Byte, デモ : JPEG から GPS 抜き出し (pure PHP で ) PHP というより、バイナリ入門といった要 素が強いですが、多分 … 、いつかお役に立 つ日が来ると思います。どうか、ご容赦 ください。

3 一応、自己紹介 http://d.hatena.ne.jp/yoya/ でプログラミン グしてて困った事とか書いてます。 http://d.hatena.ne.jp/yoya/ 一昨年位まで、数十万ユーザ規模の携帯 サイトでアプリ開発をしていました。 – その時に、 PHP で主に動画や画像のフォー マットを弄るお仕事をしていました。フレー ムワークとかよく知りません。 今も、一応 PHP でお仕事してます。あと、 C 言語もたまに使います。

4 まずは、バイナリの定義 Wikipedia より – 通常バイナリとテキストは対比して用いられ る。 テキストとはデータの内容すべてを人間 が読んで理解できる (human-readable) 表現形 式を指し、 バイナリとはそうでない表現形式 を指すことが多い。 なので、本発表では、バイナリファイル の事を、 – テキストエディタで開いて読めない文字とか 記号が表示されるようなファイル。 という事にしておきます。

5 バイナリの実例 linux 等 UNIX 系 OS には ( 多分 ) hexdump とい うコマンドがあります。 -C オプションが 便利。 % hexdump -C aria.gif % hexdump -C kuriboo.png

6 バイナリの実感 先頭の4文字を見るとファイルの種類が 大体分かるようになっていて、その後ろ にはよく分からないデータが続いてます。 普通はここで読むのを諦めるのですが、 このよく分からないデータを PHP で解釈 して、欲しいデータを抜き出す方法につ いて説明します。

7 PHP とバイナリ PHP の string 型でバイナリ処理が 簡単 に出来るよ! というのが今回、紹介する Tips の肝です。 (注 ) PHP6 では UTF-8 対応したり取りやめたりと 怪しいので、今回の発表はとりあえず、 PHP5(PHP4 も多分大丈夫 ) only での話しだと思って ください。

8 本当に PHP の string 型でバイナリ 処理できるの? ぱっと思いつく不安としては、 \0 文字列終端 8bit スルー

9 ( 不安その 1) \0 は? C 言語が典型で、 \0 を文字列の ( 最後を表す ) 終端 マークとして使う処理系も結構ある。 string 型を バイナリデータとして使う場合に、間に \0 が入る 事で途中で切れないかという不安。 簡単に確認 → 確認完了 \0 で途切れない。

10 ( 不安その 2) 8bit スルー? 1 文字は 1byte で、 1byte は 8bit で構成されますが、 US-ASCII は 7bit で表現できるので、先頭 1bit が特 別扱いされたりしない? 8bit スルーです。日本語とかも入れられるし当然 ですね。

11 バイナリを取り込んでそのまま出 力 でも、細かい事考えなくても、バイナリファイルを取 り込んで、何も変えずに出力して同じデータに戻れば、 OKですよね。 入力をそのまま出力して、同じデータになりました。 後は、この途中でデータを分割したり結合したり、入 れ替えたりすれば編集できる事になります。

12 Byte 処理 String 関数が使えます http://php.net/manual/ja/ref.strings.phphttp://php.net/manual/ja/ref.strings.php – strlen ( データサイズを調べる。呼ぶたびに文字数を数えたりし ないので安心 ) ☆ – substr ( データから一部を抜き出す ) ☆ – substr_replace ( データの一部を入れ替える ) – strrev ( データの前後を逆にする ) Endian 処理に便利 ☆ – chr 数値 => 文字 ( バイナリ 1byte) ☆ – ord 文字 ( バイナリ 1byte) => 数値 ☆ – bin2hex ダンプするのに便利です ☆ これだけ分かれば大丈夫。 ( 今回の発表では、☆のついた関数 が出てきます ) pack 関連は次回発表の機会があれば … さて、 JPEG で試してみます。

13 JPEG の解析 今回のデモ iPhone で写真を撮ると、位置情報が付くらしい JPEG から GPS 情報を抜き出す (JPEG > Exif(Tiff) > GPSInfo) 2 重にくるまれてる …

14 初めの一歩 まずファイルを開いてみる 見てても読めないし法則も分からない。

15 JPEG フォーマットでググる 「 JPEG フォーマット 仕様」でググってみ る – http://siisise.net/jpeg.html#format http://siisise.net/jpeg.html#format 16bit は 2 byte に相当。 ffxx で区切るらしい。 眺めていると、何となくピンと来るはず。

16 JPEG を marker で分割してみる この ffxx のマークで分割してみます。 http://siisise.net/jpeg.html#format – Marker の種類 FFD8, FFE0, FFDB, FFC4, FFC0, FFC1, FFDD, FFDA … etc

17 データを切り出すクラス まず、バイナリの先頭から Byte を切り出 すクラスを作成 内部的に、何処まで読んだか (cursor) を覚 えておいて、そこから substr で一部の データを切り出すだけのクラス

18 marker 一個目 http://siisise.net/jpeg.html#format によれ ば、初めのマーカーは FFD8 (Start of Image) http://siisise.net/jpeg.html#format

19 Marker 逐次処理 SOI (Start of Image) と EOI (End of Image) は マーカー (2byte) だけ APP0, APP1, 等殆どのタグはマーカー (2byte) に続いて、長さ (2byte) 、その後ろ にデータが ( 長さ -2 分の ) 続く SOS は EOI の直前まで続く ( 途中で RST と いう別のタグがあるが、今回は中にまと めちゃう )

20 Marker 逐次処理コード

21 Marker 分割結果 分割できた

22 Marker の照らし合わせ

23 GPS 情報は Exif にくるまれてる 「 JPEG GPS フォーマット 仕様」でググる – http://detail.chiebukuro.yahoo.co.jp/qa/question_det ail/q1217494967 http://detail.chiebukuro.yahoo.co.jp/qa/question_det ail/q1217494967 「 JPEG exif フォーマット 仕様」でググる – http://www2.airnet.ne.jp/~kenshi/exif.html http://www2.airnet.ne.jp/~kenshi/exif.html – http://hp.vector.co.jp/authors/VA032610/JPEGFormat /AboutExif.htm http://hp.vector.co.jp/authors/VA032610/JPEGFormat /AboutExif.htm – http://www.exif.org/Exif2-2.PDF http://www.exif.org/Exif2-2.PDF APP1 に入っているらしい。 ディレクトリ構造らしい。 ( 面倒そう …)

24 Little Endian ? Exif は Little Endian を使う事があるらしい バイナリを 16 進で見た並び => 対応する整 数値 – Big Endian – Little Endian

25 ByteStream の LittleEndian 対応

26 APP1 の抽出 JPEG を分解するついでに $jpeg_chunk 配列 に格納して $jpeg_chunk 配列から APP1 で Exif のデータ を抜き出す

27 Exif 分解コード

28 Exif 分解結果

29 GPSInfo の分解 GPS は GPSInfo というタグに入っているら しい 「 JPEG exif GPSInfo フォーマット 仕様」で ググる – http://www2.airnet.ne.jp/~kenshi/exif.html http://www2.airnet.ne.jp/~kenshi/exif.html

30 GPSInfo の分解コード

31 GPSInfo 分解結果 N は北緯、 E は東経、他は座標値等々 …

32 Bit 処理は … Byte を更に細かく区切った Bit 処理 (0,1 の データ ) もお話したかったのですが、時間 に収まらなかったのでもし要望があれば 次回に発表します。

33 まとめ バイナリは大抵 TLC 構造か、難しくても ディレクトリ構造なので、これらが分か れば大抵処理可能。今回は両方処理しま した。 TLC 構造 ディレクトリ構造

34 蛇足的な Tips PHP の閉じタグ ?> は使わない。 ?> の後ろに改行やゴ ミ文字があった場合に、テキストなら最後にゴミが付 くだけで大きな問題になりにくいが、バイナリだと致 命的。 $s = '' 等、文字列でも文字数が 0 だと、 $s{3} = 'A' とし た場合に、 array([3] => "A"); のように配列になる。 $s = ‘ ‘( 空白 1 文字 ) 等としとくと、 string(4) " A" のように 思った通りいく。足りない分は 0x20( スペース ) で padding されるのに注意 C 言語なら文字列から1文字抜き出して ASCII コードと して使えるが、 PHP の場合は文字は ord で ASCII コード 値に変換して、文字に戻す時は chr() を通す必要があ る。

35 次回予告 ( ?) 今回、 PHP らしくない力づくのスマートでない手 法の紹介でした。 もし、次回の要望があれば、 Flash SWF の書き換え について発表したいです。 Flash SWF は bit と signed 処理の組み合わせがあっ たりと、そこそこ面倒なので、今回の発表から外 しました。 Google 検索 : yoya swfed

36 あ…あ… ここまで頑張っておいて何ですが … /php-5.2.9/ext/exif/ http://php.net/manual/ja/function.exif-read- data.php http://php.net/manual/ja/function.exif-read- data.php var_dump(exif_read_data($argv[1])); !!!!!!!!

37 以上です ありがとうございました。


Download ppt "PHP でバイナリプログラミン グ 2010/05/11 よや"

Similar presentations


Ads by Google