· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.HEAP —› Сравнение бинарных файлов.

Посл.отвђт Сообщенiе


Дата: Ноя 16, 2004 02:18:02 · Поправил: Asterix

Есть ли что готовое, умеющее сравнивать файлы различающегося размера, чтоб
могло находить повторяющиеся и отсутствующие блоки и выводило результат
типа(+ текстовые данные о количестве повторяющихся блоков и др.):
FF FF
FF FF
EB EB
87 C3
0F FF
BE BE
D3 D3
83 83
C2 C2
   C3
A9 A9
8D 8D
45 45
F4   
83 83
CA CA
08 08
E8 E8

   - совпадающие байты
   - не совпадающие байты
   - отсутствующие байты
   - добавленные байты


Дата: Ноя 16, 2004 06:09:47 · Поправил: Black_mirror

Asterix
Скорее всего нету, так как задача имеет далеко не единственное решение. Например берём два файла, в одном записано abcd, а в другом acbd. Их можно интерпретировать двумя способами:
a a    
  c    
b b    
c      
d d

a a    
b      
c c    
  b      
d d


А что будет с большими файлами?..


Дата: Ноя 16, 2004 07:47:23

Asterix
fc.exe /b file1 file2?


Дата: Ноя 16, 2004 08:25:19

q_q
fc.exe /b file1 file2?
Не подойдет оно. Нужно было не побайтное сравнение, а определение наличия вставленных\вырезанных блоков.

Asterix
Нечто подобное в Hex Workshop есть, только оно логи выдает несколько странные по виду.


Дата: Ноя 16, 2004 12:02:55

Black_mirror
Не понял я, что ты имел ввиду под двумя способами?
Первая колонка для первого файла, вторая для второго.
Байт либо есть в первом и отсутствует во втором файле, или его не было в первом но появился во втором, кстати таких байтов может быть несколько.
А ещё хорошо если б все совпадающие блоки перед выводом результата были свёрнуты(как RadAsm сворачивает процедуры)


Дата: Ноя 16, 2004 13:18:12

попробуй в UltraEdit есть возможность сравнить два файла. Может то что надо... вроде как он так и делает.


Дата: Ноя 16, 2004 15:54:38

Asterix
Я исправил сообщение, чтобы было нагляднее.
А сказать хотел я следующее: для некоторых участков может быть очень несколько вариантов того как их понимать. Вот еще один пример:
file1: abcdef
file2: fedcba
Здесь шестью способами можно выбрать совпадающий символ( больше одного символа здесь совпасть не может). И выбрав например d в качестве такого символа у нас еще есть насколько вариантов выбрать какой символ из первого файла был пропущен во втором: a,b или c. И какой символ был добавлен во второй файл: c,b или a.


Дата: Ноя 16, 2004 15:58:39

Asterix
„Есть ли что готовое, умеющее сравнивать файлы различающегося размера“
В Linux есть утилита diff, делающая это
для текстовых файлов - можно взять ее текст
и переработать. Вроде даже встречал bindiff,
но не поручусь. В давние-давние времена
мой приятель нашел готовую утилиту -
ему надо было измения в большой базе данных
на дискетах в Москву возить :-) Помню
только абревиатуру , типа MFT ( видимо
modify file tool) - наверняка она
у меня в архивах есть. Ну и патчеры, если
хорошо порыскать, можно найти готовые.
Кстати и fc, если запустить в режиме
"принудительно ASCII" - /L, выдает
достаточно приемлимый результат, который
только надо доработать "напильником".
Можно в нем увеличить буфер "синхронизации",
но одно но - для бинарников он какие-то
куски пропускает.....
Кстати, сейчас проверил TotalCommander -
там тоже можно отключить двоичное сравнение,
но результат текстовый - увы.


Дата: Ноя 16, 2004 16:21:42

Black_mirror
Я теперь понял.
Поэтому такое сравнение довольно нетривиальная задача ;-)
Тут нужно делать множество проходов, сначала искать максимально совпадающие блоки, возможно даже такой анализ без интерактивного участия пользователя невозможен..


Дата: Ноя 16, 2004 16:28:14

Black_mirror
> А что будет с большими файлами?..

До 30 Мб меня пока устроило бы :-)

Хотя сейчас нужно сравнить всего-то ~1 Mb файл


Дата: Ноя 16, 2004 17:55:43

Asterix
Есть алгоритм который позволяет найти наибольшую общую подпоследовательность за время O(nm) (так что с 30М файлами наверно будет тормозить), где n-длина первого файла, а m-длина второго файла.

Работает он следующим образом:
вход: f1[n],f2[m]

c[n][m];//здесь в ячейке c[i][j] будет храниться длина максимальной
        //подпоследовательности для префиксов f1[i] и f2[j]
        //(для упрощения алгоритма будем считать,
        //что за пределами этой матрицы находятся нули)
d[n][m];//ну а здесь в ячейке d[i][j] будет указанно
        //откуда мы в неё попали '<'-слева,'^'-сверху,'г'-из c[i-1][j-1]
       
for(int i=0;i<n;i++)
  for(int j=0;j<m;j++)
    if(f1[i]==f2[j]){
      c[i][j]=c[i-1][j-1]+1;
      d[i][j]='г';
    }else 
      if (c[i-1][j]>c[i][j-1]){
        c[i][j]=c[i-1][j];
        d[i][j]='^';
      }else{ 
        c[i][j]=c[i][j-1];
        d[i][j]='<';
      }
Потом начиная с элемента [n-1][m-1] и двигаясь по направлению указанному в матрице d можно будет востановить подпоследовательность. Если (f1[i]==f2[j])&&d([i][j]=='г') то нужно вывести f1[i](или f2[j] так как они равны), как элемент входящий в подпоследовательность.


Дата: Ноя 16, 2004 18:35:10

Black_mirror
> Есть алгоритм который позволяет найти наибольшую общую подпоследовательность

Я конечно не готов реализовать сейчас такое сравнение, но обсудить можно ;-)
Т.е. ты предлагаешь найти сначала наибольшую совпадающую последовательность, потом каким-то образом найденный участок исключить из поиска и искать дальше, тогда будет найдена вторая по размеру совпадающая последовательность, и т.д.?


Дата: Ноя 16, 2004 19:31:23

Asterix
Алгоритм ищет не совпадающие подстроки, а максимально длинную подпоследовательность. Это значит что ёё символы не обязательно идут подряд в исходной последовательности(строке). Причём он выдаёт не все подпоследовательности а одну из них. А вообще возможное их число экспоненциально зависит от длины исходных последовательностей. Например для последовательностей abcdefgh и badcfehg существует 2^4=16 подпоследовательностей длины 4. Удвоив длину исходных последовательностей можно получить 256 самых длинных подпоследовательностей. Вот пример замечательных последовательностей: abcabcabca и acbacbacba. Число самых длинных подпоследовательностей в них равно 2 в степени N, где N - число блоков abc или cba(первая a не считается).


Дата: Ноя 16, 2004 20:45:04

Black_mirror
Констатирую.. Ты меня окончательно запутал %)

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


Дата: Ноя 17, 2004 12:19:50

Asterix

Попытаюсь тогда описать алгоритм, используемый
в fc. Заполняем "буфер синхронизации" ( до 199 строк)
и ищем совпадающие куски( в fc - это строка).
Если таковых нет - "сбой синхронизации".
Если есть - продвигаем указатели в 2-х файлах
на место ,где совпадающий кусок кончился
и повторяем процедуру.
Кстати в программе diff этот метод доведен
до совершенства - там нет "сбоя синхронизации".
+++++++++++++++++++++++++++++++++++
FC я нередко использую, чтобы понять,
где я "испортил" свою программу. Если
встречаю "сбой синхронизации" - анализирую
кусок вручную, выкидываю и продолжаю.
Если же ты хочешь сравнивать бинарки
с байтовыми( или мелкими) вкраплениями,
то тогда без теории не обойтись - придется
ввести "меру различия" и использовать
ее вместо побайтного сравнения.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.078