PHPbinary

247 Views

June 06, 24

スライド概要

PHPでバイナリ変換

profile-image

バイナリはともだち。こわくないよ

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

PHPでバイナリ変換 プログラミング 〜 前提知識から openpear/IO_Bit の紹介、応用事例まで 〜 “よや” <[email protected]>

2.

自己紹介  六本木の方でWeb関連の仕事をしてます  バイナリ変換プログラミングが趣味です 1101 1101 神は人に 2進数を 与えたもう

3.

発表題目  (pure) PHP でバイナリ変換プログラミング  ここで云う pure は PHP の標準関数だけでという意味です chr strlen substr ord str_pad strcmp substr_replace strrev  Web 開発に飽きてきた人向けの発表  前半はバイナリのおさらいをします 。。ていうか PHP はホント楽です。JavaScript でのバイナリ処理に比べれば。。

4.

発表内容  バイナリについて  ビット(Bit)とバイト(Byte)について  PHP でバイト(Byte)処理  PHP でビット(Bit)処理  openpear/IO_Bit パッケージの紹介  IO_Bit の応用事例 (IO_SWF, IO_Zlib)

5.

バイナリについておさらい  バイナリって何?  本来は、コンピュータが処理し易い 0,1 の2進値データ  世間的には、テキスト以外のデータ (狭義のバイナリ)  エディタで開いて文字化けするデータ GIFファイル (php.gif)

6.

バイナリとテキスト  1バイトで0〜255の値を表現できるけど、テキストはそ の一部しか使わない。(日本語の話は棚に置きます) 0~0x19 0x20~0xf9 !”#… ABC… 012… abc… 0x80~0xff この辺りの 値が化けて 表示される  バイナリの方がより多くの情報を詰められる

7.

バイナリの実例  バイナリの種類  マルチメディア系ファイル (JPEG, PNG, MPEG, AVI…)  実行ファイル (exe, a.out, jar, …)  ネットワーク上の通信データ (TCP, ISDN, …)  暗号化されたデータ (zip, gzip, …) 色々ありますネ!

8.

バイナリ処理の目的  Web サービスではテキスト以外に画像/動画データや、 場合によると生の通信データを扱う事がある  それらのデータを独自に変換する事で  より多くの種類のクライアント端末でサービスが受けられ たり  通信データ量を減らせたり  エディタで開いて読めないから諦める。だと勿体ない

9.

ビット(Bit)とバイト(Byte)  コンピュータの処理(入出力や編集等)する単位  バイナリ処理はこれらの単位でデータを操作する バイト列 43 57 53 06 00 48 2c 00 78 9c b9 6b バイナリ バイナリ ビット列 00100011 01010111

10.

ビット(Bit) (おさらい)  ビット(Bit)について  0と1を用いて2通りの状態を表現したもの  ビットを並べると4通り8通りと表現の幅が広がる 0, 1 0 1 00, 01, 10,11 2通り (0〜1) 000, 001, 010, 011, 100, 101, 110, 111 000 111 8通り (0〜7) 00 11 4通り (0〜3) 00 01 10 11 00000000, 00000001, 00000010,00000011, … …, 11111101, 11111110, 11111111 0 000 00 0 0 1 111 11 1 1 256通り (0〜255)

11.

バイト(Byte)  バイト(Byte)とは  本来は、(欧米の)1文字を表すのに必要なビットの集まり  狭義にはビットを8つまとめた単位  16進数で表現する事が多い (バイナリエディタの表示) 0 000 00 0 0 1 111 11 1 1 4Bit で 16進1文字 00 FF これ丸毎で 1バイト 8Bit で 16進2文字 実例 (JPEG の頭) FF D8 FF E0

12.

バイナリエディタを使う  バイナリエディタ諸々  Macintosh なら 0xED、Windows なら Stirling, Bz Editor  手動で弄るのが面倒になったら PHP の出番です。

13.

ここから本題 PHP & Byte

14.

PHP とバイナリと String型  PHP の String 型でバイナリ処理が出来る  PHP は String 型に対し文字としての特別な事をしない PHP における文字列型は、バイトの配列と整数値 (バッファ長) で実装されています。 バイト列を文 字列に変換する方法については何の情報も持って おらず、完全にプログラマ任せとなっています。  http://www.php.net/manual/ja/language.types.string.php#languag e.types.string.details  8bitスルー。 ¥0終端もない ← この辺りの心配は無用  つまり、バイト(Byte)単位の処理は PHP でも簡単

15.

String 型でバイト処理  ファイル入出力 ファイル file_get_contents file_put_contents input output  連結と分解 $c = $a . $b 連結 $a $c $b $b = substr($a, $x, $y) 分解 $a $x $b $y ファイル

16.

String 型でバイト処理 ord,chr  バイナリと整数値との相互変換 (string) $b = ord($a) (integer or float) バイナリ 整数値 $a $b $a = chr($b) 実行例 $a = ‘Yoya’; $b = ord($a[0]); echo $b; Y 実行結果  89 = (0x59) Y o $b = 89; $c = 111; $a = chr($b).chr($c); echo $a; 実行結果  Yo

17.

String 型でバイト処理 Endian  2バイト以上のバイナリと整数値の相互変換  Big Endian (MSB First) バイナリ 整数値 x y 12 34 (x*0x100)+y 0x1234 = 4660  Little Endian (LSB first) バイナリ 整数値 x y 12 34 x+(0x100*y) 0x3412 = 13330

18.

String 型でバイト処理 BigEndian  バイナリと整数値の相互変換 (Big Endian) $b = unpack(‘n’, $a) 整数値 バイナリ $a x y (x*256)+y  pack で逆変換 $b[1] $b = unpack(‘N’, $a) バイナリ $a w x y z 整数値 $b[1] (((((w*256)+x)*256)+y)*256)+z

19.

String 型でバイト処理 LittleEndian  バイナリと整数値の相互変換 (Little Endian) $b = unpack(‘v’, $a) 整数値 $b[1] バイナリ $a x y x+(y*256)  pack で逆変換 $b = unpack(‘V’, $a) バイナリ $a w x y z 整数値 $b[1] w+(256*(x+(256*(y+(256*z)))))

20.

バイト処理の注意点  $a[0]  文字列を配列のように参照すると、($a の 0 番目の数値でなく)、 0番目の文字を切り出したものが取得できる。  $a[0] は substr($a, 0, 1) と同じ (C言語出身者は多分ココで躓く)  unpack(‘N’, … と ‘V’の PHP bug  N, V は unsigned long (32ビット値)のはずだが、実際は signed long(符号付き)の値が出てくる  負の値が出てきたら 4294967296 を足して補正  pack は正でも負でも受理してくれる。

21.

バイト処理の実例 JPEG分解  例えば) JPEG 画像のサイズを抜き出す  http://www.w3.org/Graphics/JPEG/ ← 仕様はココ height ここにサイズ が入っている width  JPEG 情報要素 JPEG SOI APP1 DQT SOF0 DHT SOS RST EOI

22.

バイト処理の実例 JPEG形式  JPEG chunk data format (以下の3パターン) FF?? & ! FF00 SOI,EOI APP,DQT, SOF0 RSTx Marker Marker Length Data Marker 2 bytes 2 bytes 2 bytes Length 2 bytes Data 次のchunkまでscan  SOF0 の中身 SOF0 Marker Marker =0xffc0 Length Data P height width 2 bytes 2 bytes 1 byte 2 byte 2 byte

23.
[beta]
バイト処理の実例 JPEGサイズ
 Code

Sample

 これで、

width, height
が抽出できる

<?php
$data = file_get_contents($argv[1]); // JPEGfile input
for ($i = 1 ; $i < strlen($data) ; $i++) {
switch(ord($data[$i++])) { // chunk marker
case 0xD8: case 0xD9: // SOI (or EOI)
break;
// skip
default:
$len = unpack('n', substr($data, $i, 2));
$i += $len[1];
break;
// skip
case 0xC0: // SOF0
$sof0 = unpack('CP/nH/nW', substr($data, $i + 2, 5));
echo "width:{$sof0['W']} heigth:{$sof0['H']}\n";
exit (0);
// OK
}
}

24.
[beta]
バイト処理の実例 GIF, PNG (簡単)
 ついでに
 GIF の

画像サイズ

 PNG の

画像サイズ

GIF
6 bytes

witdh

height

<?php
$data = file_get_contents($argv[1]); // GIF file input
$size = unpack(’vW/vH', substr($data, 6, 4));
echo "width:{$size['W']} heigth:{$size['H']}\n”;

PNG
16 bytes

witdh

height

<?php
$data = file_get_contents($argv[1]); // PNG file input
$size = unpack(’NW/NH', substr($data, 16, 4));
echo "width:{$size['W']} heigth:{$size['H']}\n”;

25.

ここからビットの話 PHP & Bit

26.

PHP でビット処理  論理演算を使ったビット取り出し処理 1Byte $a 0 000 00 0 0 1 111 11 1 1 & $b = $a & (1 << 3); (1 << 3) 0 0 0 0 1 0 0 0 3つ $c = ($a & (1 << 3) >> 3; $b 0 0 0 0 1 Bit $c 0 1 000 3つ $c = $b >> 3; 3 を一般化して $n に 0 1 $c = ($a & (1 << $n) >> $n;

27.

PHP でビット読み出し (Read)  頭から1Bit 毎に読み出し 1Byte 0 000 00 0 0 1 111 11 1 1 & 0 0 000 0 0 0 11 1 1Bit x8 0 0 1 1 シフト 0 0 0 0 0 0 1 1 1 1 1 1

28.

PHP でビット書き込み (Write)  Bit を連結して Byte を生成 1Byte $a 0 000 00 0 0 1 111 11 1 1 | ← bit or 1Bit x8 0 0 1 1 (1 << 3) 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3つ | ← bit or 0 000 10 0 0 0 0 000 0 0 0 1 111 11 1 1 $c = $a | (1 << $n); 1Byte 0 000 00 0 0 1 111 11 1 1

29.

IO_Bit の紹介  Openpear 〜 IO_Bit  http://openpear.org/package/IO_Bit ビット処理のユーティリティです。いちい ち、pack v したり、incremental に offset を 処理するのが面倒だという人向けです。利 用に制限はかけません。コピーも改変もご 自由にどうぞ。MIT ライセンスにしました。

30.

IO_Bit の使い方  Byte 入出力 $binary = file_get_contents($argv[1]); $bit = new IO_Bit(); $bit->input($binary); echo $bit->getUI8(); // get unsigned integer 8bit (=1 byte) // $bit->putUI8(0x37); // echo $bit-<output();  Bit 入出力 $binary = file_get_contents($argv[1]); $bit = new IO_Bit(); $bit->input($binary); echo $bit->getUIBit(); // get unsigned integer bit (=1 bit) // $bit->putUIBit(1); // echo $bit-<output();

31.

IO_Bit の応用例  openpear/IO_SWF (この後で説明)  Flash の実行ファイル(SWF)を編集  openpear/IO_Zlib (時間があったら説明)  Zlib 圧縮されたデータを伸長する

32.

IO_SWF の紹介  Openpear 〜 IO_SWF  http://openpear.org/package/IO_SWF SWF バイナリを解釈/編集する為のライブラリです。 IO_Bit が必要で す。主に Flash Lite 1.x/2.x を対象にしています。利用に制限はかけま せん。コピーも改変もご自由にどうぞ。MIT ライセンスにしました。 IO_SWF

33.

IO_SWF の使い方  使い方 $swfed = new IO_SWF_Editor(); // インスタンス生成 $swfed->parse($swfdata); // SWFバイナリ読み込み // 何らかの編集するメソッドを呼ぶ echo $swfed->build(); // 編集結果の SWF バイナリを出 力

34.

IO_SWF の利用例  SWF ファイルの解析 $swfdata = file_get_contents($argv[1]); $swfed = new IO_SWF_Editor(); $swfed->parse($binary); $swfed->dump(array(‘hexdump’ => true));  SWF 内コンテンツの入れ替え list($prog_name, $swf_file, $bitmap_id, $bitmap_file) = $argv; $swf_data = file_get_contents($swf_file); $bitmap_data = file_get_contents($bitmap_file); $swfed = new IO_SWF_Editor(); $swfed->parse($swf_data); $swfed->replaceBitmapData($bitmap_id, $bitmap_data); echo $swfed->build(); // 入れ替え後のSWF バイナリ出力

35.

IO_SWF の実験デモ  端末上で動作デモ

36.

IO_Zlib の紹介  Openpear 〜 IO_Zlib  http://openpear.org/package/IO_Zlib Zlib フォーマットの分解ルーチンです。 Inflate(伸張)は動作しますが、deflate(圧縮) は btype:0 (=無圧縮)のみ対応します。

37.

そもそも Zlib って?  データ圧縮アルゴリズムに Deflate というモノがあり、 そのコンテナ形式  Deflate の入れ物として有名なものに GZip と Zlib がある  詳しくはここにリンクまとめ  → http://pwiki.awm.jp/~yoya/?Deflate  GZip は gzip コマンドで生成されるファイル形式  Gzip はファイル名やタイムスタンプが入れられるが、 純粋に圧縮したい場合は、より簡略な Zlib 形式が用いら れる。

38.

Zlib について  ハフマン符号と LZ77 を組み合わせた圧縮。  ハフマン符号は符号の出現頻度に応じて、頻出する符号に 短いビット列、稀な符号に長いビット列を割り当てる事で データ量を減らす手法  LZ77 は同じパターンがある時にはその繰り返しの長さを指 定する事で、データ量を減らす手法  真面目に話すと一日かかるので、説明はココまで。  ハフマン符号はビット単位の処理が必要な符号化方式  IO_Bit の出番!

39.

IO_Zlib の使い方と動作デモ  使い方 $zlib = new IO_Zlib(); // インスタンス生成 $zlib->parse($zlibdata); // Zlib 圧縮データ読み込み // 何らかの編集するメソッドを呼ぶ echo $zlib->build(); // 伸長結果のデータを出力  端末で動作デモ

40.

エクスキューズ  実は、IO_SWF は SWFEditor というPHP拡張に似た機能が あります。  http://sourceforge.jp/projects/swfed/  更に、IO_Zlib は標準関数に gzuncompress があります。  http://php.net/manual/ja/function.gzuncompress.php  IO_Zlib はあくまでサンプルという事で。

41.

要望  他の言語で、これに似た発表があれば教えて下さい。

42.

以上  ご清聴ありがとうございました