如何在另一个二进制文件中找到一个二进制文件的偏移量?

Cyr*_*cki 7 linux large-files binary files

我有两个二进制文件。
几百公斤之一,其他几千兆字节。
我想知道整个较小的文件是否包含在较大的文件中,如果是,那么与较大文件开头的偏移量是多少。
我只对精确匹配感兴趣,即整个文件是否包含在另一个文件中。
这两个文件都是二进制文件。
是否有任何现有的工具/单线可以做到这一点?

max*_*zig 5

我想不出现有的工具。

grep -F --binary --byte-offset --only-matching似乎足够接近 - 但你无法使用 来逃避换行符-F。并且cmp只允许跳过字符。diff似乎也没有多大帮助。

但它是具有像样库的编程语言中的一些行。例如,作为使用 Boost 的 C++ 程序:

#include <boost/algorithm/string/find.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <cassert>
#include <iostream>
using namespace boost;
using namespace boost::algorithm;
using namespace boost::iostreams;
using namespace std;

int main(int argc, char **argv)
{
  if (argc != 3) {
    cerr << "Call: " << argv[0] << " PATTERN_FILE SRC_FILE\n";
    return 3;
  }
  mapped_file_source pattern(argv[1]);
  mapped_file_source src(argv[2]);
  iterator_range<const char*> p_range(pattern.data(),
      pattern.data() + pattern.size());
  iterator_range<const char*> s_range(src.data(), src.data() + src.size());
  iterator_range<const char*> result = find_first(s_range, p_range);
  if (result) {
    size_t pos = result.begin()-s_range.begin();
    cout << pos << '\n';
    return 0;
  }
  return 1;
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样编译它(当程序源保存为 时find.cc):

$ make CXXFLAGS="-Wall -g" LDLIBS="-lboost_iostreams" searchb
Run Code Online (Sandbox Code Playgroud)

要测试它:

$ dd if=WTF_-_EPISODE_277_RACHAEL_HARRIS.mp3 of=t skip=232323 bs=1 count=4K
$ ls -l t
-rw-r--r-- 1 juser users 4096 2012-05-31 15:24 t
$ ./searchb t WTF_-_EPISODE_277_RACHAEL_HARRIS.mp3
232323
Run Code Online (Sandbox Code Playgroud)

输出是源文件中的匹配位置。

如果不包含该文件,则退出状态为1

更新:与此同时,我已经用多种语言(C/C++/Python/Rust/Go)实现了这个简单的工具,并将这些实现包含在我的实用程序存储库中。寻找searchb*。Python 实现是最短的实现,并且不需要任何外部依赖项。