Сравнить бинарные файлы Linux

Обновлено: 21.11.2024

В операционных системах, которые различают текстовые и двоичные файлы, diff обычно считывает и записывает все данные как текст. Используйте параметр –binary, чтобы вместо этого заставить diff читать и записывать двоичные данные. Этот параметр не влияет на POSIX-совместимую систему, такую ​​как GNU или традиционный Unix.

Как сравнить два двоичных файла в Unix?

Если вы хотите сравнить два файла побайтно, вы можете использовать программу cmp с параметром –verbose ( -l ), чтобы отобразить значения каждого отличающегося байта в двух файлах. С GNU cmp вы также можете использовать опцию -b или --print-bytes, чтобы отобразить ASCII-представление этих байтов. Дополнительную информацию см. в разделе Вызов cmp.

Что такое двоичный файл Unix?

Двоичный файл – это любой файл, содержащий хотя бы некоторые данные, состоящие из последовательностей битов, которые не представляют собой обычный текст. Двоичные файлы используются для изображений, звука, исполняемых (то есть запускаемых) программ и сжатых данных (включая документы, созданные большинством программ обработки текста). …

Сравнивает ли meld двоичные файлы?

У этого инструмента есть приятная функция, которой мне немного не хватает в meld. Вы можете сравнить двоичные файлы, такие как e. грамм. растровые изображения. содержат двоичные данные, сохраненные нашими приложениями. Было бы неплохо иметь это в meld, тем не менее, meld — отличный инструмент!

Как узнать, совпадают ли два двоичных файла?

Используйте команду cmp, чтобы проверить, совпадают ли два файла побайтно. Команда cmp не перечисляет различия, как команда diff. Однако это удобно для быстрой проверки того, являются ли два файла одинаковыми или нет (особенно полезно для двоичных файлов данных).

Как узнать, совпадают ли два файла в Linux?

Возможно, самый простой способ сравнить два файла — использовать команду diff. Вывод покажет вам различия между двумя файлами. Знаки указывают, находятся ли дополнительные строки в первом ( ) файле, предоставленном в качестве аргументов.

Какая команда используется для сравнения файлов в UNIX?

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

Какой самый простой способ (с помощью графического инструмента или командной строки в Ubuntu Linux) узнать, совпадают ли два двоичных файла или нет (за исключением отметок времени)? Мне не нужно на самом деле извлекать разницу. Мне просто нужно знать, одинаковы они или нет.

На справочной странице cmp конкретно указано, что он выполняет побайтовое сравнение, поэтому я использую его по умолчанию для двух двоичных файлов. diff построчно и даст вам один и тот же ответ Да/Нет, но, конечно, не тот же дамп в стандартный исходящий поток. Если строки длинные, потому что, возможно, это не текстовые файлы, я бы предпочел cmp . diff имеет то преимущество, что вы можете указать сравнение каталогов и -r для рекурсии, тем самым сравнивая несколько файлов в одной команде.

15 ответов 15

Стандартный diff unix покажет, совпадают файлы или нет:

Если команда не выводит никаких результатов, это означает, что файлы не имеют различий.

Похоже, у diff есть проблемы с очень большими файлами. Я получил diff: память исчерпана при сравнении двух файлов 13G.

Интересный результат. diff говорит вам, что они "бинарные" файлы. Поскольку все файлы можно считать двоичными, это странное утверждение.

Вы можете сообщить об идентичных файлах с помощью опции: diff -s 1.bin 2.bin или diff --report-identical-files 1.bin 2.bin Это показывает, что файлы 1.bin и 2.bin идентичны

У меня есть два исполняемых файла, я знаю, что они разные, потому что я скомпилировал и запустил их, но все приведенные здесь параметры diff и cmp оценивают их как идентичные. Почему? .

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

остановится ли cmp, когда найдет первое отличие, и отобразит ли его, или пройдёт до конца файлов?

cmp имеет "тихий" режим: -s, --quiet, --silent - подавлять весь обычный вывод. Я еще не проверял, но думаю, что он остановится на первом отличии, если оно есть.

Я проверил это прямо сейчас для cmp (GNU diffutils) 3.7. Как уже было сказано в ответе, cmp останавливается на первом различии и указывает его так: файл1 отличается от файла2: символ 14, строка 1.

Я обнаружил, что Visual Binary Diff — это то, что я искал, и он доступен на:

Mac OS X через Homebrew:

Хорошо. Я /думал/ хотел только знать, отличаются ли файлы; но возможность легко увидеть точные различия была намного полезнее.Когда я добирался до конца файла, это имело тенденцию к segfault, но это не имело значения, оно все еще работало.

Это должен быть принятый ответ, так как это намного лучший метод, чем пресный и бесполезный вывод канонической команды diff.

Используйте sha1 для генерации контрольной суммы:

Если бы у вас была контрольная сумма только для одного из файлов, это было бы полезно, но если у вас есть оба файла на диске, в этом нет необходимости. diff и cmp сообщат вам, если они отличаются, без каких-либо дополнительных усилий.

SHA1 уже имеет одну публичную коллизию (shattered.io) и, вероятно, несколько непубличных. Одно столкновение может быть использовано для создания бесчисленного количества конфликтующих файлов. Вместо этого используйте SHA2 для хеширования.

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

Используйте hexdump -v -e '/1 "%02x\n"', если вы хотите сравнить и точно увидеть, какие байты были вставлены или удалены.

Meld также работает с двоичными файлами, если они не преобразованы в шестнадцатеричный формат. Он показывает шестнадцатеричные значения для вещей, которых нет в наборе символов, в противном случае это обычные символы, что полезно с двоичными файлами, которые также содержат текст ASCII. Многие так и делают, по крайней мере начинают с волшебной строки.

Вы можете использовать хеш-функцию MD5, чтобы проверить, являются ли два файла одинаковыми, при этом вы не увидите различий на низком уровне, но это быстрый способ сравнить два файла.

Если оба хэша MD5 (вывод команды) одинаковы, то эти два файла не отличаются.

Можете ли вы объяснить, почему вы проголосовали против? SHA1 имеет 4 голоса «за», и если OP считает, что есть вероятность, что два файла могут быть одинаковыми или похожими, шансы на столкновение невелики и не заслуживают голосования против MD5, но против голосования SHA1, кроме как потому, что вы слышали, что вы должны хешировать свой пароли с SHA1 вместо MD5 (это другая проблема).

не уверен в причине, но чистый cmp будет более эффективным, чем вычисление любой хеш-функции файлов и их сравнение (по крайней мере, только для двух файлов)

если два файла большие и находятся на одном диске (не ssd), вариант md5 или sha* может быть быстрее, потому что диски могут читать два файла последовательно, что экономит много движений головы

Я проголосовал против, потому что вы опубликовали второстепенный вариант более раннего (плохого) решения, когда это должно было быть комментарием.

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

-b не сравнивает файлы в "бинарном режиме". На самом деле «с GNU cmp вы также можете использовать параметр -b или --print-bytes, чтобы показать ASCII-представление этих байтов». Это именно то, что я нашел, используя предоставленный вами URL-адрес руководства.

Виктор Ярема, я не знаю, что вы подразумеваете под "бинарным режимом". cmp по своей сути является бинарным сравнением, на мой взгляд. Параметр -b просто печатает первый отличающийся байт.

Для поиска дефектов флэш-памяти мне пришлось написать этот скрипт, который показывает все блоки размером 1 КБ, содержащие различия (а не только первый, как это делает cmp -b)

Отказ от ответственности: я взломал скрипт за 5 минут. Он не поддерживает аргументы командной строки и не поддерживает пробелы в именах файлов

Diff со следующими параметрами выполнит двоичное сравнение, чтобы проверить, отличаются ли файлы вообще, и выведет, совпадают ли файлы:

Если вы сравниваете два файла с одинаковыми именами в разных каталогах, вместо этого вы можете использовать эту форму:

OS X Эль-Капитан

Короткий ответ: запустите diff с параметром -s.

Подробный ответ: читайте ниже.

Вот пример. Начнем с создания двух файлов со случайным двоичным содержимым:

Теперь давайте сделаем копию первого файла:

Теперь test1.bin и test2.bin должны отличаться:

<р>. а test1.bin и copyoftest1.bin должны совпадать:

Но подождите! Почему нет вывода.

Ответ: так задумано. В идентичных файлах вывод невозможен.

Но есть разные коды ошибок:

К счастью, теперь вам не нужно каждый раз проверять коды ошибок, потому что вы можете просто использовать ключ -s (или --report-identical-files ), чтобы сделать diff более подробным:

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

Попробуйте radiff2, который является частью дизассемблера радара2. Например, с помощью этой команды:

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

Мои любимые, использующие xxd hex-dumper из пакета vim:

1) с помощью vimdiff (часть vim)

Если md5sum одинакова, двоичные файлы одинаковы

Чтобы этот совет был практичным, вам придется изменить хэш MD5 на SHA2. В наши дни любой ноутбук может генерировать коллизию в MD5 и на основе этого одного префикса коллизии (2 файла одинакового размера, одного префикса и одного и того же MD5) для создания бесконечного количества коллизирующих файлов (с одинаковым префиксом, другим конфликтующим блоком, одним и тем же суффиксом) < /p>

wxHexEditor бесплатен и способен сравнивать большие файлы размером до 2^64 байт (2 ExaByte). Имеет графический интерфейс. Кроссплатформенность. Множество функций.

Чтобы получить его бесплатно, выберите один из следующих вариантов:

Ниже приведено то же предложение, что и выше. Но с подробностями, если они вас интересуют.

• Шестнадцатеричный (Hex) редактор. Это полезно для обратного проектирования.

• Кроссплатформенность. Linux, Mac OS, Windows

• Простой в использовании графический интерфейс пользователя (GUI)

• Поддерживает очень большие файлы размером до 2^64 байт (2 эксабайта)

• Сравните два больших файла рядом (diff). При желании выведите список и выполните поиск всех различий.

• Очень быстрый поиск

• Используйте небольшой объем оперативной памяти.

• Не создавайте временные файлы. Таким образом, он занимал очень мало места для хранения.

• Темная или светлая тема

• Многоязычный 15 языков

• Если вам нравится это приложение, продемонстрируйте свою поддержку авторам и участникам с помощью:

Мне нужно сравнить два бинарных файла и получить результат в виде:

для каждого отдельного байта. Итак, если файл1.bin

в двоичной форме, а файл2.bin

Я хочу получить что-то вроде

Есть ли способ сделать это в Linux? Я знаю о cmp -l, но он использует десятичную систему для смещений и восьмеричную для байтов, которых я хотел бы избежать.

Поскольку вы не можете ответить на этот вопрос (поскольку вы не пользователь), я голосую за закрытие. Двоичный diff, явно запрошенный здесь, совсем не полезен, и я склонен думать, что вы хотите что-то полезное, если вы вставите один байт в начало файла, должны ли все байты быть помечены как разные? Не зная этого, это просто слишком расплывчато.

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

Также обновлен метод о радаре, но я все еще думаю, что этот вопрос не по теме и слишком расплывчатый.

16 ответов 16

Это напечатает смещение и байты в шестнадцатеричном формате:

Или введите $1-1, чтобы первое напечатанное смещение начиналось с 0.

К сожалению, функция strtonum() специфична для GAWK, поэтому для других версий awk, например mawk, вам потребуется использовать функцию преобразования восьмеричного числа в десятичное. Например,

Выделено для удобства чтения:

@gertvdijk: strtonum специфичен для GAWK. Я полагаю, что Ubuntu ранее использовала GAWK по умолчанию, но в какой-то момент переключилась на mawk. В любом случае можно установить GAWK и настроить его по умолчанию (см. также man update-alternatives). См. мой обновленный ответ для решения, которое не требует strtonum .

@Rodrigo: Этот и другие методы просто покажут, различаются ли файлы. Мой ответ соответствует требованию OP, чтобы показать, в чем заключаются различия.

Преимущество cmp перед ответом с xxd заключается в том, что он на несколько порядков быстрее работает с большими файлами!

Как заметил ~quack:

Это отлично сработало для меня (с opendiff в OS X вместо vimdiff ) — представление по умолчанию, предоставляемое xxd, позволяет движку сравнения отслеживать побайтовое сравнение. С простым (необработанным) шестнадцатеричным кодом, просто подходящим по столбцу с помощью fold , diff попытается свернуть/сгруппировать случайные данные в файлах, которые я сравниваю.

Эта команда плохо работает для удаления добавления байтов, так как каждая следующая строка будет смещена и будет видна как измененная diff . Решение состоит в том, чтобы поместить 1 байт в строку и удалить столбец адреса, как это было предложено Джоном Лоуренсом Аспденом и мной.

разница + xxd

Попробуйте diff в следующей комбинации замены процесса zsh/bash:

  • -y показывает различия рядом друг с другом (необязательно).
  • xxd — это инструмент командной строки для создания шестнадцатеричного дампа двоичного файла.
  • Добавьте -W200 к diff для более широкого вывода (до 200 символов в строке).
  • Для цветов используйте colordiff, как показано ниже.

разница в цвете + xxd

Если у вас есть colordiff , он может раскрасить вывод diff, например:

В противном случае установите через: sudo apt-get install colordiff .

вимдифф + xxd

Вы также можете использовать vimdiff , например

  • если файлы слишком большие, добавьте ограничение (например, -l1000 ) для каждого xxd

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

Мое любимое решение, мне очень помогло! С опцией --suppress-common-lines будут отображаться только разные строки

Есть инструмент под названием DHEX, который может выполнить эту работу, и есть еще один инструмент, который называется VBinDiff.

Для строго командной строки попробуйте jojodiff.

DHEX великолепен. Вы хотите сравнивать двоичные файлы. Подайте ему два файла, и он перенесет вас прямо к сравнительному просмотру, выделяя различия, с легкой возможностью перейти к следующему отличию. Также он может работать с большими терминалами, что очень полезно на широкоэкранных мониторах.

Я предпочитаю VBinDiff. DHEX использует процессор даже в режиме ожидания, я думаю, что он все время перерисовывается или что-то в этом роде. Однако VBinDiff не работает с широкими терминалами. Но адреса все равно становятся странными с широкими терминалами, так как у вас есть более 16 байтов на строку.

Сжатые файлы @DanielBeauyat будут совершенно другими после того, как вы встретите первый другой байт. Вывод вряд ли будет полезен.

@1111161171159459134 jdiff является частью «набора» программ для синхронизации и исправления различий, обнаруженных jdiff. Но, как сказал Марк Рэнсом, это было бы неразумно для сжатых файлов; исключение составляют «синхронизируемые» сжатые форматы (например, созданные gzip --rsyncable), в которых небольшие различия в несжатых файлах должны иметь ограниченное влияние на сжатый файл.

Метод, который работает для добавления/удаления байтов

Создайте тестовый пример с одним удалением байта 64:

Если вы также хотите увидеть ASCII-версию символа:

Протестировано на Ubuntu 16.04.

Я предпочитаю od xxd, потому что:

  • это POSIX, а не xxd (поставляется с Vim)
  • имеет -An для удаления столбца адреса без awk .

Преимуществом этого метода является то, что od чрезвычайно мощен. В частности, он позволяет сравнивать объекты длиннее байта, например. 32-битные числа с плавающей запятой. Пример: diff -u .

При использовании шестнадцатеричных дампов и текстовых различий для сравнения двоичных файлов, особенно xxd , добавление и удаление байтов становится сдвигом в адресации, что может затруднить просмотр. Этот метод указывает xxd не выводить адреса и выводить только один байт в строке, что, в свою очередь, точно показывает, какие байты были изменены, добавлены или удалены. Вы можете найти адреса позже, выполнив поиск интересных последовательностей байтов в более «нормальном» шестнадцатеричном дампе (вывод xxd first.bin ).

Я бы рекомендовал hexdump для вывода двоичных файлов в текстовый формат и kdiff3 для просмотра различий.

Можете ли вы добавить что-нибудь к этому ответу о его свойствах (без «Изменить:», «Обновить:» или подобных)? Например, как он обрабатывает один вставленный байт (имеет ли смысл вывод после этой точки?)?

Hexdiff – это программа, предназначенная именно для того, чтобы делать то, что вам нужно.

Он отображает шестнадцатеричный (и 7-битный ASCII) двух файлов один над другим, с выделением любых различий. Посмотрите в man hexdiff команды для перемещения по файлу, и простой q завершит работу.

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

Инструмент анализа встроенного ПО binwalk также имеет эту функцию через параметр командной строки -W / --hexdump, который предлагает такие параметры, как отображение только различающихся байтов:

В примере OP при выполнении binwalk -W file1.bin file2.bin :

Добавить | меньше -r для пейджинга.

Возможно, это не совсем ответ на вопрос, но я использую это для сравнения двоичных файлов:

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

Можете ли вы добавить что-нибудь к этому ответу о его свойствах (без «Изменить:», «Обновить:» или подобных)? Например, как он обрабатывает один вставленный байт (имеет ли смысл вывод после этой точки?)?

DHEX — это больше, чем просто еще один шестнадцатеричный редактор: он включает режим сравнения, который можно использовать для простого и удобного сравнения двух двоичных файлов. Поскольку он основан на ncurses и поддерживает темы, он может работать в любом количестве систем и сценариев. Благодаря использованию журналов поиска можно легко отслеживать изменения в различных итерациях файлов.

Добро пожаловать в SuperUser!Хотя это программное обеспечение выглядит так, как будто оно может решить проблему OP, чистая реклама категорически не одобряется в сети Stack Exchange. Если вы связаны с редактором этого программного обеспечения, сообщите об этом факте. И попробуйте переписать свой пост так, чтобы он меньше походил на рекламу. Спасибо.

Я никоим образом не связан с dhex. Я скопировал описание автора в сообщение, потому что существует ограничение на минимальную длину сообщения

Ниже приведен Perl-скрипт colorbindiff, который выполняет двоичное сравнение, принимая во внимание изменения байтов, но также добавление/удаление байтов (многие из предложенных здесь решений обрабатывают только изменения байтов), как в текстовая разл. Он также доступен на GitHub.

Результаты отображаются рядом с цветами, что значительно облегчает анализ.

Вы можете использовать инструмент gvimdiff, включенный в пакет vim-gui-common

sudo apt-get update

sudo apt-get install vim-gui-common

Затем вы можете сравнить два шестнадцатеричных файла с помощью следующих команд:

Я написал простой скрипт для сравнения двоичного файла. Он напечатает первый другой фрагмент (40 байт) и смещение:

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

Но можно ли его использовать для произвольных двоичных файлов? Похоже, что эта страница указывает на то, что она полезна только для сравнения исполняемых файлов, которые были дизассемблированы с помощью Hex-Rays IDA Pro.

Продуктом с открытым исходным кодом для Linux (и всего остального) является Radare, который специально предоставляет radiff2 для этой цели.

Но это безумие. Потому что, как было сказано, если вы вставите один байт в первый байт в файле, вы обнаружите, что каждый последующий байт отличается, и поэтому diff будет повторять весь файл для фактической разницы в один байт.

Чуть практичнее radiff -O . -O для ""Выполнять сравнение кода со всеми байтами, а не только с фиксированными байтами кода операции""

Как и IDA Pro, Radare является основным инструментом для бинарного анализа, и вы также можете показать дельта-диффинг с помощью -d или отобразить дизассемблированные байты вместо шестнадцатеричного с помощью -D .

Допустим, у меня есть файл abc размером 4 ГБ на локальном компьютере. Я загрузил его на удаленный сервер через SFTP, это заняло несколько часов.

Теперь я немного изменил файл (вероятно, максимум 50 МБ, но не последовательные байты в этом файле) локально и сохранил его в abc2 . Я также сохранил исходный файл abc на локальном компьютере.

Как вычислить двоичную разницу между abc и abc2?

Я мог только отправить файл исправления (вероятно, не более 100 МБ) на удаленный сервер вместо повторной загрузки всего файла abc2 (это снова заняло бы несколько часов!), и воссоздать abc2 на удаленном сервере из abc и только исправления .

Локально, вместо того, чтобы тратить 8 ГБ на резервное копирование как abc, так и abc2 , я мог бы сохранить только abc + patch , поэтому потребовался бы diff , но здесь я ищу что-то, что могло бы работать для любого необработанного двоичного формата, это могло бы быть ZIP-файлами, исполняемыми файлами или даже другими типами файлов.

PS2: Если возможно, я не хочу использовать rsync ; Я знаю, что он может эффективно реплицировать изменения между двумя компьютерами (без повторной отправки данных, которые не изменились), но здесь я действительно хочу иметь файл исправления, который можно воспроизвести позже, если у меня есть и abc, и patch .

5 ответов 5

Для второго приложения/проблемы я бы использовал программу резервного копирования с дедупликацией, такую ​​как restic или borgbackup , вместо того, чтобы пытаться вручную отслеживать «исправления» или различия. Программа резервного копирования restic позволяет создавать резервные копии каталогов с нескольких компьютеров в один и тот же репозиторий резервных копий, дедуплицируя данные резервного копирования как среди фрагментов файлов с отдельной машины, так и между машинами. (У меня нет опыта работы с borgbackup, поэтому я ничего не могу сказать об этой программе.)

Расчет и сохранение разницы между файлами abc и abc2 можно выполнить с помощью rsync .

Это пример, когда abc и abc2 составляют 153 МБ. Файл abc2 был изменен путем перезаписи первых 2,3 МБ файла некоторыми другими данными:

Мы создаем патч для преобразования abc в abc2 и называем его abc-diff :

Сгенерированный файл abc-diff – это фактический файл diff (ваш "файл исправления"), а abc-diff.sh – это короткий сценарий оболочки, который создает для вас rsync:

Этот скрипт изменяет abc таким образом, что он становится идентичным abc2 , учитывая файл abc-diff :

Теперь файл abc-diff можно перенести туда, где у вас есть abc . С помощью команды rsync --read-batch=abc-diff abc вы примените исправление к файлу abc , преобразовав его содержимое так, чтобы оно совпадало с файлом abc2 в системе, где вы создали diff.

Повторное применение исправления кажется безопасным.Сообщений об ошибках нет, и содержимое файла не меняется (контрольная сумма MD5 не меняется).

Обратите внимание, что если вы не создадите явное "обратное исправление", нет возможности легко отменить его применение.

Я также протестировал запись модификации размером 2,3 МБ в другое место в данных abc2, чуть дальше (около 50 МБ), а также в самом начале. Сгенерированный «патч» имел размер 4,6 МБ, что позволяет предположить, что в патче были сохранены только измененные биты.

Читайте также: