私は C++ を使って約 6 か月しか経っていないので、コードで愚かな間違いを犯したことをお詫びします。
バイナリ ファイルを streambuf に読み込み、streambuf で特定のシーケンスを検索し、バイナリ ファイルのシーケンス開始オフセットと、バイナリ ファイルで特定のシーケンスが見つかった識別子を報告するプロジェクトに取り組んでいます。
検索するシーケンスは、snortRules ベクトルの各インデックスが int のベクトルとして格納される単一のシーケンスである snortRules と呼ばれる vector> に格納されます。
最終的には、一致するはずの別のファイルと比較するために見つかったオフセットと特定のシーケンスを表示するテキスト ファイルを作成する必要がありますが、今のところ、結果をコンソール ウィンドウに出力するだけです。
私のコードは、1 つの問題を除くすべてのシーケンスを見つけたと報告しているため、機能しているようです。何らかの理由で、シーケンスが見つかった場所のオフセットが繰り返されることがあります。たとえば、出力は次のようになります。
101521 #655
101816 #656 <--This output is correct
101816 #657 <--This output is wrong and should have offset 101865
101893 #658 <--This output is correct
101893 #659 <--This output is wrong and should have offset 102084
102105 #660
102325 #661
102378 #662
私の問題は、streambuf の pubseekoff を使用してオフセットを正しく取得していないことだと思います。
私のコードは次のとおりです。
fstream binFS(binName, ios::in | ios::binary); //create stream
streambuf* binBuff = binFS.rdbuf(); //create streambuf from filestream
int currentChar; //ascii code of current character from binary file
streamsize offset; //location of first character of rule in binary file
do
{ //until the end of binary file
for(unsigned i=0; i<snortRules.size(); ++i)
{//start by finding the begining of current rule
do
{ //check binBuff until first char of first rule is found.
currentChar = binBuff->sgetc();
if( snortRules[i][0] == currentChar )//binBuff->sgetc() ) //compare short rule 1st char to curtent position
{ //match save offset and compare rest of rule
offset = binBuff->pubseekoff(0,ios::cur); //set the offset to current postion
bool checkNext = true; //bool to break loop when checking rules if not matching
for(unsigned srIdx=0; srIdx < snortRules[i].size() && checkNext == true; ++srIdx)
{ //loop through current rule comparing characters
if(snortRules[i][srIdx] == currentChar)
{ //match check if end of rule or advance character to compare to next in rule
if( srIdx == snortRules[i].size()-1)
{ //match write the offset of fist character of rule and which was matched
std::cout<<offset<<" #"<<i+1<<endl; //write to console for debugging purposes will write to text file when working
++i; //increment rule to next when exact match found
}
else
{ //not at the end of the rule so continue to compare next characters
currentChar = binBuff->snextc(); //set currentChar to next char to be checked by for loop
}
}
else
{ //no match break out and continue
checkNext == false; //set flag to break for loop because characters didnt match
}
}
}
else
{ //no match check next character in binBuff
//offset = binBuff->pubseekoff (0,binFS.cur, binFS.in); //set the offset to current postion
currentChar = binBuff->snextc(); //get next char in binBuff
//offset = binBuff->pubseekoff (0,binFS.cur, binFS.in); //set the offset to current postion
}
}while( currentChar != streambuf::traits_type::eof() ); //stop checking if end of file reached
}
}while( binBuff->snextc() != streambuf::traits_type::eof() ); //stop checking if end of file reached
stackoverflow.com と cplusplus.com で pubseekoff のドキュメントと例を見つけようとしましたが、見つけたものはあまり意味がなく、正直なところ、それが私の問題であると 100% 確信していません...
どんな助けや提案も大歓迎です!