поиск большого двоичного значения из еще большего двоичного файла - PullRequest
4 голосов
/ 04 июля 2011

Как видно из заголовка, я хотел бы получить grep достаточно большой (около 100 МБ) двоичный файл для двоичной строки - эта двоичная строка чуть меньше 5 КБ.

Я пробовал grep с использованием -Pвариант, но это, кажется, возвращает совпадения только тогда, когда шаблон занимает всего несколько байтов - когда я беру около 100 байтов, он больше не находит совпадений.

Я также пытался bgrep .Первоначально это работало хорошо, однако, когда мне нужно было расширить шаблон до длины, которую я сейчас имею, я просто получаю ошибки «неверная / пустая строка поиска».

Ирония в том, что в Windows я могу использовать HxD для поискафайл, и я нахожу его в экземпляре.Что мне действительно нужно, так это инструмент командной строки Linux.

Спасибо за вашу помощь,

Simon

Ответы [ 4 ]

2 голосов
/ 04 июля 2011

Скажем, у нас есть пара больших двоичных файлов данных.Для большого файла, который не должен совпадать, мы создаем файл размером 100 МБ, содержимое которого содержит все байты NUL.

dd ibs=1 count=100M if=/dev/zero of=allzero.dat

Для файла, который мы хотим сопоставить, создайте сто случайных мегабайт.

#! /usr/bin/env perl

use warnings;

binmode STDOUT or die "$0: binmode: $!";

for (1 .. 100 * 1024 * 1024) {
  print chr rand 256;
}

Выполните его как ./mkrand >myfile.dat.

Наконец, извлеките известное совпадение в файл с именем pattern.

dd skip=42 count=10 if=myfile.dat of=pattern

Я предполагаю, что вам нужны только совпадающие файлы (-l) и хотите, чтобы ваш шаблон обрабатывался буквально (-F или --fixed-strings).Я подозреваю, что у вас может быть ограничение длины с -P.

У вас может возникнуть желание использовать опцию --file=PATTERN-FILE, но grep интерпретирует содержимое PATTERN-FILE как шаблоны, разделенные символом новой строки, так что в вероятном случае, когда ваш шаблон размером 5 КБ содержит символы новой строки, вы столкнетесь с проблемой кодирования.

Так что надеюсь, что ARG_MAX вашей системы достаточно велик и продолжайте.Обязательно процитируйте содержание pattern.Например:

$ grep -l --fixed-strings "$(cat pattern)" allzero.dat myfile.dat
myfile.dat
0 голосов
/ 04 июля 2011

Поскольку строка, которую вы ищете, довольно длинная.Вы можете воспользоваться реализацией алгоритма поиска Бойера-Мура, который очень эффективен, когда строка поиска очень длинная

http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm

В вики также есть ссылки на некоторый пример кода.

0 голосов
/ 04 июля 2011

Возможно, вы захотите взглянуть на простой скрипт на Python.

match= (b"..." 
    b"...."
    b"..." ) # Some byte string literal of immense proportions
with open("some_big_file","rb") as source:
    block= read(len(match))
    while block != match:
        byte= read(1)
        if not byte: break
        block= block[1:]+read(1)

Это может надежно работать как в Linux, так и в Windows.

0 голосов
/ 04 июля 2011

Попробуйте использовать grep -U, который обрабатывает файлы как двоичные файлы.

Кроме того, как вы определяете шаблон поиска? Может потребоваться экранирование, чтобы выжить при расширении параметров оболочки

...