C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[32]: バイナリコード内の16進数での文字列検索 [1]


(過去ログ 52 を表示中)

[トピック内 72 記事 (21 - 40 表示)]  << 0 | 1 | 2 | 3 >>

■28536 / inTopicNo.21)  Re[8]: バイナリコード内の16進数での文字列検索
  
□投稿者/ しょう (10回)-(2008/11/27(Thu) 14:17:53)
No28533 (.SHO さん) に返信

お返事有難うございます。

> ところで「特定の文字列」というのは1バイトなんですか?
固定のバイト数は持ちません。
上記では日付で例えましたが、実際は複数のキーワードとして入力可能になります。

> バイナリファイルをcoutしても、まともに読めるように表示されなくて当然ですよね。
> > ってなると、わかんなくなちゃいます?
わかんなくなっちゃいました(笑)
化けるのは正しいとしても、どうやったら16進数をcoutに出力できるのでしょう?
引用返信 編集キー/
■28537 / inTopicNo.22)  Re[8]: バイナリコード内の16進数での文字列検索
□投稿者/ なちゃ (216回)-(2008/11/27(Thu) 14:19:11)
そんな無茶な…
引用返信 編集キー/
■28538 / inTopicNo.23)  Re[9]: バイナリコード内の16進数での文字列検索
□投稿者/ しょう (11回)-(2008/11/27(Thu) 14:21:02)
No28537 (なちゃ さん) に返信

お返事有難うございます。

> そんな無茶な…
どの辺が無茶なんでしょう?
実現不可能な仕様なのでしょうか?
引用返信 編集キー/
■28540 / inTopicNo.24)  Re[8]: バイナリコード内の16進数での文字列検索
□投稿者/ .SHO (204回)-(2008/11/27(Thu) 14:26:12)
No28534 (しょう さん) に返信

> 簡単にまとめさせてください。

いろいろ課題はありますが、とりあえず Jitta さんが書かれた

> 文字列なんてものはない。全て数値です。その数値に、人間が見て意味のある形を割り当てたところが「文字」。
> その文字が複数連続して現れるのが「文字列」。

というのを、きちんと理解しないと話がややこしくなるだけですね。
引用返信 編集キー/
■28542 / inTopicNo.25)  Re[9]: バイナリコード内の16進数での文字列検索
□投稿者/ .SHO (206回)-(2008/11/27(Thu) 14:46:15)
No28536 (しょう さん) に返信

> 化けるのは正しいとしても、どうやったら16進数をcoutに出力できるのでしょう?

32 30 30 38 2F 31 32 2F 31 33
みたいに出力したいってことですか?
引用返信 編集キー/
■28543 / inTopicNo.26)  Re[9]: バイナリコード内の16進数での文字列検索
□投稿者/ しょう (12回)-(2008/11/27(Thu) 14:46:27)
2008/11/27(Thu) 14:48:27 編集(投稿者)

No28540 (.SHO さん) に返信

お返事ありがとうございます。

そうです。
とりあえず16進数で表示するにはC++を使ってどう実現するのかから知らないと、扱いもなにもないかと思いまして。
引用返信 編集キー/
■28557 / inTopicNo.27)  Re[10]: バイナリコード内の16進数での文字列検索
□投稿者/ Jitta on the way (234回)-(2008/11/27(Thu) 18:56:59)
No28543 (しょう さん) に返信
> 2008/11/27(Thu) 14:48:27 編集(投稿者)
>
> ■No28540 (.SHO さん) に返信
>
> お返事ありがとうございます。
>
> そうです。
> とりあえず16進数で表示するにはC++を使ってどう実現するのかから知らないと、扱いもなにもないかと思いまして。

だから16進数とか文字とかじゃなく、数値、もっとわかりやすく書くと、整数値なんだって。整数値、つまり int を文字列にするには、どうしたらいい?
引用返信 編集キー/
■28568 / inTopicNo.28)  Re[5]: バイナリコード内の16進数での文字列検索
□投稿者/ dogatana (11回)-(2008/11/27(Thu) 21:07:13)
No28522 (しょう さん) に返信
> ■No28518 (Jitta さん) に返信
>
> FILE *fp;
> char buf[BUFSIZ];
> fp = fopen("A.hoge","rb");
> while(fgets(buf,BUFSIZ,fp){
> cout << buf << endl;
> }

バイナリファイルであればfgets()で読むのではなく、
size_t rsize = fread(buf, 1, sizeof(buf), fp);
とfread()関数を使うのが良いですね。

でも、ファイルサイズがBUFSIZ以下であれば良いですが、そうでない場合は工夫が必要です。
100MB程度であれば、ファイルサイズ分のメモリを割り当て、fread()で一気に読むなんてのもありかと。
データを書き換えるということなので、全データをメモリに持っておくと楽だと思います。

引用返信 編集キー/
■28569 / inTopicNo.29)  Re[8]: バイナリコード内の16進数での文字列検索
□投稿者/ dogatana (12回)-(2008/11/27(Thu) 21:24:36)
No28534 (しょう さん) に返信
> すいません、自分の質問内容を読んでイマイチな気がしたので簡単にまとめさせてください。
>
> ・A.hogeというバイナリファイルがある。
> ・このファイルにはどこかに日付があり、この日付を書き換える機能を作る。
> ・該当個所をstirlingというツールで確認した所、下記のようである。
>
> [16進数]         [文字列]
>  32 30 30 38 2F 34 2F 31  2008/4/1
>
> ・この内容を例えば"2008/12/13"にしたい場合、
>
> [16進数]           [文字列]
>  32 30 30 38 2F 31 32 2F 31 33  2008/12/13
>
>  という形になる。つまり長さの変動がある。→後ろのアドレスが全部変わる。
>
> ・16進数のアドレスは後続処理で参照する為、文字列を直接編集するより16進数を書き換えた方がいいと判断。
>
> よって、「16進数で検索・変更を行う必要がある」というのが今回の機能です。

プログラムを作る場合、処理が分からなくなったら、より小さな処理に分けていくと分かりやすくなりますよ。
ツールを作られているということですが、大まかにいって
1)検索データを指定し、
2)そのデータが特定のファイルに存在するかどうか検索する
3)検索の結果、必要であればその内容を書き換える
という処理があると思います。

想像するに、1)のところで、GUIもしくはコマンドライン引数などで "32 30 30 38" などと指定した文字列から、
検索用のデータを作りだす方法が分からないということではないですか?

例えば char data[4] = "\x32\x30\x30\x38" とか char data[] = {0x32, 0x30, 0x30, 0x38 } のようなデータを
生成する方法のこと。

検索そのものは、STLのsearch()関数が使えます。
対象となるファイルのデータがすべてメモリ上にあればとても簡単です。

引用返信 編集キー/
■28572 / inTopicNo.30)  Re[6]: バイナリコード内の16進数での文字列検索
□投稿者/ ま (169回)-(2008/11/27(Thu) 23:49:59)
1バイトは8ビット
8ビットは255までの正数値が表現できる。
16進数は、4ビットで表現する。0〜9、A〜Fまでの16通りだから。
2進数にすると、0000 が 0 で、1111 が F になる。
1バイト=8ビットだから、0000 0000 は 00 で、0011 0000 は文字の 0 。

char[] hexstring = "0123456789ABCDEF";
のhexstring の配列インデックスに 0011 0000 をそれぞれ指定すれば16進数値を2桁の文字列
に表現できそうですよね?

で、1バイトは8ビットであり、文字の 0 は、2進数に直すと、00110000 だから、16進数の値は
4ビットで表現することを考慮すると、00110000 を4ビットずつに分割しなければならない。

1バイトの上4ビットは、下4ビットの16倍だから、16で割れば上4ビットが取り出せます。
逆に、下4ビットは、16で割った余りですね。

unsigned char a = 00110000b;
unsigned char div = a / 16;
unsigned char mod = a % 16;
っていう表現で16進数の値を上下4ビットずつに分割できました。
ここで見慣れない unsigned ってのが出てきました。符号拡張されないようにするために unsigned
ってのを指定します。Jitta さんが指摘している通り、1バイトは正数値では、-128 〜 127 の値を
取りますが、符号無しで考えると、0 〜 255 の値を取ります。
div と mod は 0 〜 15 の値を取るので、さきに提示した hexstring のインデックスに当てはめると
char upperNibble = hexstring[div];
char lowerNibble = hexstring[mod];
で、upperNibble に 3 が、lowerNibble に 0 が取得出来ました。

こんな面倒なことやらんでも printf って便利な奴があるから勉強してこいつで変換してあげればOKよ。
但し現状、右も左も分かってないみたいだから、コーディング遅れてもいいから、1週間入門本買って
勉強した方がいいよ。今のまま皆さんに教えてもらったところでまた躓くのがオチ。

次回躓いて教えを請う時はもう少し発展的なスレッド展開を目指した方がいいと思いません?
何を言っているのか意味不明、調べ方もわからんし、適当な教材も無いし、上司に聞くに聞けないし
・・・なんて泥沼は卒業しましょ。いくら粘っても模範解答は出てこないです。この雰囲気だと。

別に STL なんて使わなくても出来るし。STL って言われてもピンとも来ないでしょう?
(dogatena さんを批判しているわけではありません。)

ただのC言語さえ意味不明なのにね、さらにSTLだのboost だの言われてもね〜、でしょ?


引用返信 編集キー/
■28578 / inTopicNo.31)  Re[7]: バイナリコード内の16進数での文字列検索
□投稿者/ あんどちん (25回)-(2008/11/28(Fri) 00:40:17)

No28572 (ま さん) に返信
> unsigned char a = 00110000b;
これ通りますか?
unsigned char a = 0x30; /* 00011 0000 */
の方が無難かと

引用返信 編集キー/
■28580 / inTopicNo.32)  Re[8]: バイナリコード内の16進数での文字列検索
□投稿者/ ま (170回)-(2008/11/28(Fri) 00:52:45)
No28578 (あんどちん さん) に返信
>
> ■No28572 (ま さん) に返信
>>unsigned char a = 00110000b;
> これ通りますか?
> unsigned char a = 0x30; /* 00011 0000 */
> の方が無難かと
>

ええー通らないんですか・・・00110000b って何だっけ????アセンブラか何かだったか???

がーん。
http://www.nmn.jp/~hidai/c/
ここに2進数は扱えません、って書いてある。。。


ごめんさい。


引用返信 編集キー/
■28590 / inTopicNo.33)  Re[9]: バイナリコード内の16進数での文字列検索
□投稿者/ .SHO (209回)-(2008/11/28(Fri) 08:58:39)
No28580 (ま さん) に返信

> ええー通らないんですか・・・00110000b って何だっけ????アセンブラか何かだったか???

かなり昔だけど「00110000b」を「0x30」に変換するマクロを作りました。

引用返信 編集キー/
■28593 / inTopicNo.34)  Re[7]: バイナリコード内の16進数での文字列検索
□投稿者/ Jitta (545回)-(2008/11/28(Fri) 09:07:36)
No28572 (ま さん) に返信
> ってのを指定します。Jitta さんが指摘している通り、1バイトは正数値では、-128 〜 127 の値を
> 取りますが、符号無しで考えると、0 〜 255 の値を取ります。
>
細かくてごめんなさい。「正数値」なら、0〜255 です。「整数値」なら、-128〜127 です。
引用返信 編集キー/
■28597 / inTopicNo.35)  Re[10]: バイナリコード内の16進数での文字列検索
□投稿者/ .SHO (212回)-(2008/11/28(Fri) 09:13:27)
No28543 (しょう さん) に返信

> そうです。
> とりあえず16進数で表示するにはC++を使ってどう実現するのかから知らないと、扱いもなにもないかと思いまして。

じゃぁ、まず「char c = 0x30;」の「c」を「30」と表示するプログラムを作ってみましょう。
引用返信 編集キー/
■28602 / inTopicNo.36)  Re[8]: バイナリコード内の16進数での文字列検索
□投稿者/ も (58回)-(2008/11/28(Fri) 09:22:56)
No28534 (しょう さん) に返信
> すいません、自分の質問内容を読んでイマイチな気がしたので簡単にまとめさせてください。
>
> ・A.hogeというバイナリファイルがある。
> ・このファイルにはどこかに日付があり、この日付を書き換える機能を作る。
> ・該当個所をstirlingというツールで確認した所、下記のようである。
>
> [16進数]         [文字列]
>  32 30 30 38 2F 34 2F 31  2008/4/1
>
> ・この内容を例えば"2008/12/13"にしたい場合、
>
> [16進数]           [文字列]
>  32 30 30 38 2F 31 32 2F 31 33  2008/12/13
>
>  という形になる。つまり長さの変動がある。→後ろのアドレスが全部変わる。
場合によると思うけど、これってリソースエディタで何とかなりませんかね?
exescopeとか exe リソース エディタ とかをgoogleで調べてみてください
引用返信 編集キー/
■28614 / inTopicNo.37)  Re[11]: バイナリコード内の16進数での文字列検索
□投稿者/ επιστημη (1381回)-(2008/11/28(Fri) 10:39:12)
επιστημη さんの Web サイト
2008/11/28(Fri) 10:39:39 編集(投稿者)
> じゃぁ、まず「char c = 0x30;」の「c」を「30」と表示するプログラムを作ってみましょう。

マニピュレータ絡みのとこはわかりにくいでしょうねぇ。
なのでお助け。

#include <iostream>
#include <iomanip>
...

  char c = 0x30;
  std::cout << std::setfill('0') // '0'詰め
            << std::hex          // 16進
            << std::uppercase    // 大文字
            << std::setw(2)      // 2桁
            << (static_cast<unsigned char>(c) & 0xff);

# ぶっちゃけ printf("%02X"...) の方がはるかに楽っす ^^;

引用返信 編集キー/
■28623 / inTopicNo.38)  Re[8]: バイナリコード内の16進数での文字列検索
□投稿者/ επιστημη (1382回)-(2008/11/28(Fri) 11:14:09)
επιστημη さんの Web サイト
で、バイナリ列から特定の部分列を探し出すのはどってことねぇです。

#include <algorithm>
#include <iostream>

using namespace std;

int main() {
  // 0, 1, 2, 3, ... 255 の並ぶbyte列から
  unsigned char data[256];
  for ( int i = 0; i < 256; ++i ) data[i] = static_cast<unsigned char>(i);
  // 文字列"0123"を探す
  string pattern = "0123";
  unsigned char* pos = search(data, data+256, pattern.begin(), pattern.end());
  if ( pos != data+256 ) {
    cout << "隊長見つかりました!! 先頭から " << distance(data, pos) << " 番目です。\n";
  }
}

引用返信 編集キー/
■28624 / inTopicNo.39)  Re[9]: バイナリコード内の16進数での文字列検索
□投稿者/ .SHO (220回)-(2008/11/28(Fri) 11:23:29)
No28623 (επιστημη さん) に返信

探し出す対象がファイルで data が 256 バイトとは限らないとことに
もう1つ山がありますね^^;

ファイルの内容を最初に全部読みこんじゃってもいいけど
より汎用的に作るには、読みこみながら探す方が良く
それだと search は使えないですね。
引用返信 編集キー/
■28627 / inTopicNo.40)  Re[10]: バイナリコード内の16進数での文字列検索
 
□投稿者/ επιστημη (1383回)-(2008/11/28(Fri) 11:52:32)
επιστημη さんの Web サイト
2008/11/28(Fri) 12:09:08 編集(投稿者)
> ファイルの内容を最初に全部読みこんじゃってもいいけど
> より汎用的に作るには、読みこみながら探す方が良く
> それだと search は使えないですね。

ですねー

とはいえきょうび数百MB程度のファイルなら
まるっとメモリに読み込むのどってことないから ^^;

#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

/*
  このソース自身を標準入力に食わせ、
   "C++" を "しーぷらすぷらす"
   に置換してみよぉ!
*/

int main() {
  std::istreambuf_iterator<char> first(std::cin);
  std::istreambuf_iterator<char> last;
  std::string str(first,last);
  std::cout << "before:\n" << str << std::endl;
  std::string from = "C++";
  std::string to   = "しーぷらすぷらす";
  for ( std::string::size_type pos = 0;
        (pos = str.find(from,pos)) != std::string::npos;
        pos += to.size() ) {
    str.replace(pos, from.size(), to);
  }
  std::cout << "after:\n" << str << std::endl;
}

引用返信 編集キー/

<前の20件 | 次の20件>
トピック内ページ移動 / << 0 | 1 | 2 | 3 >>

管理者用

- Child Tree -