プロが教えるわが家の防犯対策術!

いつもお世話になります。
今、検索について学習しているのですが、
文字列検索の場合はstrstrなどを使用すれば
検索できることは理解できました。

しかし、バイナリファイルの検索について理解できていません。

もし、バイナリ(画像や動画etc)ファイルの
中身を解析したい場合、

(1)JPEGなどのバイナリファイルを開く場合、fopen()でひらいてもいいのでしょうか?その他の方法ありますか?
(2)バイナリファイルを開いた後、バイナリファイルの
0xfffeなど指定する値の検索がしたい場合は
どのように検索したらいいのでしょうか?
関数や方法などありましたら教えてください。


どうぞよろしくお願い致します。

A 回答 (3件)

fopen(filename, "rb") でオープンできますね(Unix系のOSなら改行などの変更はしなくていいので "r" だけでも同じでしょうけど)。



1バイトが8ビットとして、「0xfffe を検索したい」という意味が、0xff の次のアドレス位置に 0xfe があるのを見つけたいというのであれば、エラー処理は省いて書くと、
long search(FILE *fp) /* 0xff 0xfe を検索し、その位置を返す */
{
int m = 0;// マッチ状態: 0 or 1
unsigned char c;
while (fread(&c, 1, 1, fp) == 1) {
switch (c) {
case 0xff:
if (m == 0) ++m;
else m = 0;
break;
case 0xfe:
if (m == 1) return ftell(fp);
m = 0;
break;
}
}
return -1L;/* 適当に選んだ、無さそうな位置の値 */
}
でいいのではないでしょうか。通常、入出力ライブラリ内でバッファリングがされ、システムコールが fread() 呼び出しごとに呼び出されることがないので、そんなに遅くはならないでしょう。一バイト読み出すごとに fread() を呼ぶのでは関数呼び出しのオーバヘッドが大きすぎるのであれば、自分でバッファ管理するのがいいですけどね。

ただし、0xfffe など複数バイトの値の検索では、ファイルのフォーマットにもよりますが、CPUのバイトのアドレス付け順序が関係してくるかもしれませんね。たとえば、0xfffe が 16 ビット short の値であり、リトルエンディアンのCPUであったなら、0xfe を見つけてから 0xff を見つけるようにしないとなりません。もちろん、16 ビット short の値で、ファイルの内容がすべて short のバイナリ値なのであれば、fread で short の変数をバッファにして読み出して比較するだけ(逆に2つの short を跨いで比較してはいけない)ですけどね。
    • good
    • 0
この回答へのお礼

大変丁寧な説明ありがとうございました。

お礼日時:2007/08/22 14:08

そのものズバリの答えは書きません。


自分で考える力をつけてもらうためのヒントだけ書きます。

(1)JPEGなどのバイナリファイルを開く場合、fopen()でひらいてもいいのでしょうか?その他の方法ありますか?

fopenを"rb"でオープンすれば問題ありません。
ただし、fgetsしないこと。
必ずfreadで読み出しましょう。

(2)バイナリファイルを開いた後、バイナリファイルの0xfffeなど指定する値の検索がしたい場合はどのように検索したらいいのでしょうか?関数や方法などありましたら教えてください。

専用の関数はありませんので、strstrに似た処理を自前でやりましょう。
unsigned char buff[256];
というバッファに読み込んだら、
for( i=0 ; i<(256-1) ; i++ ) {
if( (buff[i]==0xff) && (buff[i+1]==0xfe) ) {
// 該当する0xfffeコードが見つかった!
}
}
で1バイトづつ検査していきます。これをbuffにfreadできる限り繰り返します。
ただし、このプログラムのままでは256バイト目に0xffと257バイト目に0xfeがあるとバッファが別になってしまうので検索されません。
一括でファイル内容全部をバッファに読み込むか、プログラムの工夫が必要です。
プログラムの工夫は、1つはダブルバッファにする。もうひとつは、比較するのが2バイトだけなら2バイトのバッファを別に持ちます。
    • good
    • 0
この回答へのお礼

そうですね。
一度考えてチャレンジしてみます。
ありがとうございました。

お礼日時:2007/08/22 14:09

「メモリブロックどうしの比較」なら memcmp なんだけど....


JPEG なんかだと圧縮されていることも多いので, 単純に「指定したデータ」を見付けるだけでは無意味かもしれないですね.
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!