Какая информация отображает количественную разницу между двумя большими заданными файлами одинакового размера?

Обычно, чтобы выяснить, чем отличаются два бинарных файла, я использую инструменты diff и hexdump. Но в некоторых ситуациях, если даны два больших бинарных файла одинакового размера, я хотел бы видеть только их количественные различия, такие как количество областей различий, кумулятивная разница.

Пример: 2 файла A и B. Они имеют 2 diff региона, и их совокупная разница составляет 6c-a3 + 6c-11 + 6f-6e + 20-22.

File A = 48 65 6c 6c 6f 2c 20 57
File B = 48 65 a3 11 6e 2c 22 57
              |--------|  |--|
                 reg 1   reg 2

Как я могу получить такую ​​информацию, используя стандартные инструменты GNU и Bash, или мне лучше использовать простой скрипт Python? Другая статистика о том, чем отличаются 2 файла, также может быть полезна, но я не знаю, что еще и как можно измерить? Разница в энтропии? Разница в дисперсии?


person psihodelia    schedule 20.10.2011    source источник
comment
Что не так с программой cmp, которая у вас уже есть в Linux? en.wikipedia.org/wiki/Cmp_(Unix). Кроме того, если файлы имеют разный размер (или сравниваемые регионы имеют разный размер), каков результат?   -  person S.Lott    schedule 20.10.2011
comment
Ваше определение кумулятивной разницы подразумевает, что кумулятивная разница между 00 ff и ff 00 равна 0. Это задумано?   -  person Sven Marnach    schedule 20.10.2011
comment
В качестве более общего замечания: без указания цели довольно бессмысленно запрашивать другие меры различия. Вы можете рассматривать два файла как векторы (байтов) и использовать любую конечномерную векторную норму.   -  person Sven Marnach    schedule 20.10.2011
comment
@sven 1. это зависит от того, иногда мне это нужно. Но вы всегда можете просто использовать abs() или возвести различия в квадрат. 2. Цель состоит в том, чтобы иметь некоторую статистику о количественных различиях.   -  person psihodelia    schedule 20.10.2011


Ответы (2)


Для всего, кроме регионов, вы можете использовать numpy. Что-то вроде этого (не проверено):

import numpy as np
a = np.fromfile("file A", dtype="uint8")
b = np.fromfile("file B", dtype="uint8")

# Compute the number of bytes that are different
different_bytes = np.sum(a != b)

# Compute the sum of the differences
difference = np.sum(a - b)

# Compute the sum of the absolute value of the differences
absolute_difference = np.sum(np.abs(a - b))

# In some cases, the number of bits that have changed is a better
# measurement of change. To compute it we make a lookup array where 
# bitcount_lookup[byte] == number_of_1_bits_in_byte (so
# bitcount_lookup[0:16] == [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4])
bitcount_lookup = np.array(
    [bin(i).count("1") for i in range(256)], dtype="uint8")

# Numpy allows using an array as an index. ^ computes the XOR of
# each pair of bytes. The result is a byte with a 1 bit where the
# bits of the input differed, and a 0 bit otherwise.
bit_diff_count = np.sum(bitcount_lookup[a ^ b])

Я не смог найти функцию numpy для вычисления регионов, но просто напишите свою собственную, используя a != b в качестве входных данных, это не должно быть сложно. См. этот вопрос для вдохновение.

person Lauritz V. Thaulow    schedule 20.10.2011
comment
Спасибо, это выглядит как интересное решение. - person psihodelia; 21.10.2011

Один из подходов, который приходит на ум, состоит в том, чтобы немного изменить алгоритм бинарного сравнения. Например. реализация алгоритма rsync на Python. Исходя из этого, вы должны относительно легко получить список диапазонов блоков, в которых файлы различаются, а затем выполнить любую статистику, которую вы хотите сделать для этих блоков.

person janneb    schedule 20.10.2011