• ベストアンサー

バイナリファイルの検索について

いつもお世話になります。 今、検索について学習しているのですが、 文字列検索の場合はstrstrなどを使用すれば 検索できることは理解できました。 しかし、バイナリファイルの検索について理解できていません。 もし、バイナリ(画像や動画etc)ファイルの 中身を解析したい場合、 (1)JPEGなどのバイナリファイルを開く場合、fopen()でひらいてもいいのでしょうか?その他の方法ありますか? (2)バイナリファイルを開いた後、バイナリファイルの 0xfffeなど指定する値の検索がしたい場合は どのように検索したらいいのでしょうか? 関数や方法などありましたら教えてください。 どうぞよろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.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 を跨いで比較してはいけない)ですけどね。

the-ai
質問者

お礼

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

その他の回答 (2)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

そのものズバリの答えは書きません。 自分で考える力をつけてもらうためのヒントだけ書きます。 (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バイトのバッファを別に持ちます。

the-ai
質問者

お礼

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「メモリブロックどうしの比較」なら memcmp なんだけど.... JPEG なんかだと圧縮されていることも多いので, 単純に「指定したデータ」を見付けるだけでは無意味かもしれないですね.

関連するQ&A

  • バイナリファイルから文字列を検索するコマンド

    C++言語で書かれたプログラムの実行ファイルが50個ほど あり(それぞれ50MB程度)、ある関数を修正した場合に どの実行ファイルに影響があるか調べたいのですが、 ソースコードを追って依存関係を調べるのは現実的ではないため 実行ファイルの中にその関数名が含まれるかどうかで 判断しようと思っております。 ためしにFTPでパソコン上に転送して、バイナリエディタで表示し 使用している関数名が文字列として含まれていることは 確認できましたが、毎回全ファイルをFTP転送するのは避けたいので、 同様の調査をUNIXマシン上で行いたいのですが、 バイナリファイルから文字列を検索するコマンドは ありますでしょうか? OSは SUN OS5.8です。 宜しくお願いします。

  • バイナリファイル内の文字列を検索したい

    初心者で恐縮ですがよろしくお願いします。 入力された値でバイナリファイル内検索し、その値がある行を特定したいのですが、file_get_contentsしてみても歯抜けになってしまっていて、そのままの状態で文字列として取得することができません。↓でPHPはバイナリファイルも文字列として検索でいるとあったんですが・・・  http://blog.asial.co.jp/707 バイナリファイルはphpやjavascriptが該当すると認識しているんですが、正しいでしょうか?htmlゃcssファイルもバイナリファイルと言っていいんでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • C言語でファイル内の一致検索

    やりたい事は、ファイル(テキストに限らず画像等も含めて)をfopen関数で読み込んであらかじめ用意したバッファーに格納されているデータと一致する箇所をすべて検索して検索されたところをすべて列挙することです。 効率の良い(検索速度)方法で行いたいのですが、 fgetc関数を使って検索していくのとfread関数を使って一度すべてをメモリー内に読み込んで検索するのではどちらが効率がよいでしょうか? 他にも良い方法があったら教えてください。 私はFILE * ストリームポインタの仕組みがよくわかっていません。fopenをすると何が内部で行われるのでしょうか?ファイルの内容がメモリーに読み込まれるわけではないですよね?ファイル内にアクセスする時どのようにアクセスしているのかなど教えていただきたいです。そうすればどうするのが良いのかわかる気がするので。 あとこれとは別の話ですが 標準関数にあるmemmoveとstrstr関数ですが、これと同様な機能を持つstrmoveとmemmemといった関数がなかったのですが、この機能を持つ関数は用意されているのでしょうか?一般的に使われないので自分で作れということなのでしょうか?その場合どの様に実装すればよいか時間があれば参考にプログラムを書いていただけないでしょうか? よろしくお願いします。

  • フォルダーの中にあるファイルのバイナリデーターの検索を行えるソフトを探

    フォルダーの中にあるファイルのバイナリデーターの検索を行えるソフトを探しています。 環境はwindowsXPです。 フォルダーの中にあるファイルに含まれる特定のバイナリデーターを検索するソフトウェアを探しています。 ファイルを特定のバイナリエディターで開けば検索機能を使って検索できますが、ファイル数が多い場合すべて検索するのは大変です。一度に検索できるソフトはないでしょうか? 文章に含まれる文字列を探すのではなく、例えばexeファイルの中にある文字列を検索する場合バイナリデーターとして検索したいということです。できれば、アスキーかユニコードか指定できるとうれしいです。 文字検索ではなく16進数などで指定して検索でもかまいませんので知っている方は回答よろしくお願いします。

  • バイナリコードを見つけ出すツールを教えてください

    私のパソコン内にテキストコードのみで構成される拡張子がtxtやhtmlのファイルが大量にあります。 パソコンがウイルスに感染すると、パソコン内のファイルがいつの間にか変更されていることがありますが、変更されているかどうかを調べるためにバイナリコードを見つけ出すツールを探しています。 テキストコードのみで構成されていたファイルの中身が変更されていたなら、バイナリコードが付加されているはずなので、バイナリコードを見つけ出すことが出来れば、そのファイルの中身が変更されていることが分かるという判断です。 notepadでバイナリファイルを開くと、黒い四角や難しい漢字、半角のカタカナなどが表示されるので、とりあえず その黒い四角 をコピーして 試しに GrepReplaceで、検索文字列の欄に 黒い四角 をペーストして、あるファイル(テキストコードのみのファイルにバイナリファイルを結合させたファイル)の中身を検索しましたが、 黒い四角があるはずなのに、GrepReplaceでは残念ながらヒットしませんでした。 バイナリコードである 黒い四角 を検索文字列にして検索をすると、的確にヒットするツールがあれば教えてください。 またバイナリコードが含まれているかどうかについて、数多くのファイルを一括して調べることが出来るツールがあれば教えてください。

  • 文字列から文字列を検索するプログラム

    現在、C言語を学習しています。 文字列から文字列を検索する関数に「strstr]がありますが、自作関数として自分で作成する方法を考えております。 文字列から文字を検索する事は出来たのですが、文字列を検索するシーケンスがわかりません。 有識者の方、御教授よろしく御願い致します。

  • バイナリで書き込みましたがエラーが出る。原因は?

    拡張子を.wavとしてあるa.wavというファイルがあります。 fopenとfread関数を用いて以下のように読込み、 fp = fopen("a.wav","rb"); fread(data[0],4,1,fp); fopenとfwriteを用いてb.wavファイルに以下のように書き込みました。 fa= fopen("b.wav","wb"); fwrite(data[0],4,1,fa); 書き込んだb.wavファイルですが、 バイナリエディタStirlingでa.wavとb.wavファイルの中身を比較したら中身は同じでした。 しかし、a.wavファイルでは音が出力されるのに、b.wavファイルでは音が出力されずエラーが出ます。 この原因はいったいなんでしょうか? 原因がわかる方がいましたら教えていただけないでしょうか? よろしくお願いいたします。

  • PHPのfopenのバイナリモードについて

    PHPのfopen時のバイナリモードについて質問です。 PHPのマニュアルにはWINDOWSのようなバイナリとテキストモードの形式の違う システムでは、画像等のバイナリファイルを扱うときはbを付けてバイナリモードで扱うことが推奨されていますが、 WINDOWS環境でためしたところ、画像ファイルをバイナリではなくテキストモードで開いて中身のデータを読み込んで、別名でfopen("~.jpg","w")で書き込んでも、きちんと表示される画像が作成されました。 テキストモードでバイナリファイルを開いても読み込めってさらに、新規でかきこめるなら なぜ二つのモードが存在するのでしょうか? ちなみに、WINDOWSにおけるバイナリとテキストモードの違いって改行文字が ¥nか¥r¥nの違いだけでしょうか? リナックスではバイナリもテキストも中身の改行文字は¥nとなるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • バイナリファイルの通信について

    Webシステムの開発を検討しています。 サーバはJavaで開発し、クライアントはIEなどのWebブラウザではなく、VBのクライアントアプリケーションで構築しようと考えいます。 その際、問題となっている事は、バイナリファイルの通信方法です。 例えば、クライアントが起動した際にサーバからイメージファイルを送信する方法など。 バイナリファイルをテキスト文字列に変換して送信することはできると思うのですが、他には、クライアントとサーバで言語が異なる場合、一般にどのようなバイナリファイルの送信方法があるのか、色々比較した上で決めたいと思っています。 色々な送信方法や、参考Webサイトなど、ご存知の方がいらっしゃいましたらご教授願います。

  • ファイルの中身検索と表示

    Cでの作成についてなんですが、 fopenでテキストファイルを開き、テキストの中身の 特定文字が含まれている行を新に作ったファイルの中に 書き込みたいんですが、テキストの中身の検索と 抽出方法がいろいろ試してみましたがわかりません。 よろしくお願いします。