Сравнить хэши файлов python
Если вам не нужно, чтобы ваша хеш-функция была криптографически защищенной (чего я не делаю), тогда существует pyfasthash (по-видимому, pyhash), как обсуждалось здесь. К сожалению, в хэш-классах pyfasthash отсутствует метод update , использованный выше. Мне не очень повезло с пониманием того, что еще делать; смесь кода Python-C мне не по силам. Я просто читаю весь файл в память вот так:
Недостатки такого подхода:
Есть ли способ быстрее вычислить хэши моих файлов?
Я не знаю о реализации Python, но криптографически безопасные хэши, такие как SHA1 (да, я знаю) или SHA256 на современных машинах, могут быть быстрее, поскольку современные процессоры предоставляют (большую часть) их на оборудовании.
При этом, как правило, если вам нужно хэшировать большие файлы, скорость алгоритма хеширования не будет особенно важной (если это что-то достаточно быстрое) - ввод-вывод в любом случае будет медленнее.
Спасибо, @MatteoItalia. Алгоритмы pyfasthash быстрее, чем SHA1, хотя многие из них кластеризуются во время выполнения, как если бы они были привязаны к вводу-выводу. Если свопы страниц не соответствуют вводу-выводу, тогда эта умная буферизация действительно может не иметь большого значения для файлов, которые умещаются в памяти.
В примечаниях к пыхашу приведены примеры хеширования по частям.
President James K. Polk
@JamesKPolk, вы имеете в виду « hasher('hello', ' ', 'world') - это синтаксический сахар для hasher('world', seed=hasher(' ', seed=hasher('hello'))) » или мне что-то еще не хватает? Меня напугала конструкция объекта и предупреждение о том, что ни один из них не может быть равен hasher('hello world') , хотя последний мог бы выжить, если бы я всегда использовал один и тот же размер блока.
Да, я имею в виду это. Я признаю, что это довольно паршиво, и предупреждения действительно означают, что вам нужно провести некоторое тестирование. Кажется, у вас не так много хороших вариантов. Я бы поставил запрос функции, чтобы они предоставили API, который эффективно поддерживает API hashlib, но с открытым исходным кодом, поэтому вы, вероятно, получите более быстрые результаты, просто разветвив репо и сделав это самостоятельно.
Is there any simple way of generating (and checking) MD5 checksums of a list of files in Python? (I have a small program I'm working on, and I'd like to confirm the checksums of the files).
@kennytm The link you provided says this in the second paragraph: "The underlying MD5 algorithm is no longer deemed secure" while describing md5sum . That is why security-conscious programmers should not use it in my opinion.
Might be worth mentioning there are still valid reasons to use md5 that are not affected by it's brokenness for security purposes. (eg checking for bit rot in a system that uses baked in md5 creation during archival)
6 Answers 6
Note that sometimes you won't be able to fit the whole file in memory. In that case, you'll have to read chunks of 4096 bytes sequentially and feed them to the md5 method:
Note: hash_md5.hexdigest() will return the hex string representation for the digest, if you just need the packed bytes use return hash_md5.digest() , so you don't have to convert back.
There is a way that's pretty memory inefficient.
Recall though, that MD5 is known broken and should not be used for any purpose since vulnerability analysis can be really tricky, and analyzing any possible future use your code might be put to for security issues is impossible. IMHO, it should be flat out removed from the library so everybody who uses it is forced to update. So, here's what you should do instead:
If you only want 128 bits worth of digest you can do .digest()[:16] .
This will give you a list of tuples, each tuple containing the name of its file and its hash.
Again I strongly question your use of MD5. You should be at least using SHA1, and given recent flaws discovered in SHA1, probably not even that. Some people think that as long as you're not using MD5 for 'cryptographic' purposes, you're fine. But stuff has a tendency to end up being broader in scope than you initially expect, and your casual vulnerability analysis may prove completely flawed. It's best to just get in the habit of using the right algorithm out of the gate. It's just typing a different bunch of letters is all. It's not that hard.
Here is a way that is more complex, but memory efficient:
Again, you can put [:16] after the call to hash_bytestr_iter(. ) if you only want 128 bits worth of digest.
@GregS, @TheLifelessOne - Yeah, and next thing you know someone finds a way to use this fact about your application to cause a file to be accepted as uncorrupted when it isn't the file you're expecting at all. No, I stand by my scary warnings. I think MD5 should be removed or come with deprecation warnings.
I'd probably use .hexdigest() instead of .digest() - it's easier for humans to read - which is the purpose of OP.
I'm clearly not adding anything fundamentally new, but added this answer before I was up to commenting status, plus the code regions make things more clear -- anyway, specifically to answer @Nemo's question from Omnifarious's answer:
I happened to be thinking about checksums a bit (came here looking for suggestions on block sizes, specifically), and have found that this method may be faster than you'd expect. Taking the fastest (but pretty typical) timeit.timeit or /usr/bin/time result from each of several methods of checksumming a file of approx. 11MB:
So, looks like both Python and /usr/bin/md5sum take about 30ms for an 11MB file. The relevant md5sum function ( md5sum_read in the above listing) is pretty similar to Omnifarious's:
Granted, these are from single runs (the mmap ones are always a smidge faster when at least a few dozen runs are made), and mine's usually got an extra f.read(blocksize) after the buffer is exhausted, but it's reasonably repeatable and shows that md5sum on the command line is not necessarily faster than a Python implementation.
EDIT: Sorry for the long delay, haven't looked at this in some time, but to answer @EdRandall's question, I'll write down an Adler32 implementation. However, I haven't run the benchmarks for it. It's basically the same as the CRC32 would have been: instead of the init, update, and digest calls, everything is a zlib.adler32() call:
Note that this must start off with the empty string, as Adler sums do indeed differ when starting from zero versus their sum for "" , which is 1 -- CRC can start with 0 instead. The AND -ing is needed to make it a 32-bit unsigned integer, which ensures it returns the same value across Python versions.
Доброго времени суток!
Существует множество программ сравнения двух файлов.
Но какой алгоритм используется для сравнения двух хеш-функций md5.
В hashlib (Python3) такого метода нет.
Update: нужно найти 2 максимально похожих хеша.
Оценить 2 комментария
Марат: Сначала разберись, что такое md5-хеш, а то туфту какую-то спрашиваешь. Похожесть файловых хешей никакого отношения к похожести файлов не имеет.
Спасибо за ответ. Здесь моя вина. Мне нужно было сравнить несколько хешей и вывести 2 максимально похожих.
Спасибо за ответ. Здесь моя вина. Мне нужно было сравнить несколько хешей и вывести 2 максимально похожих.
По идее и при правильном MD5, результат вычисления хеша должен максимально соответствовать закону нормального распределения.
Другими словами, MD5 хеши от двух файлов с различием в один бит должны соответствовать друг другу, как произвольная выборка двух значений белого шума.
Иными словами - два хеша от двух разных файлов соответствуют друг другу, как два произвольно взятых значения.
Еще проще - хеши MD5 сравнивать бесполезно!
Вы, наверное, имеете в виду результаты хэш функций, а не сами функции? Тогда ответ прост: побайтное сравнение результатов если там хэш в сыром виде (то есть memcmp). Или посимвольное, если хэш строкой (то есть strcmp).
Спасибо за ответ. Здесь моя вина. Мне нужно было сравнить несколько хешей и вывести 2 максимально похожих.
Марат: а что такое похожесть файлов? Мой внутренний телепат предполагает, что вы хотите найти похожие изображения. Если это так, что хэш-функции тут ни при чем.
Я пытаюсь проверить два файла, загруженных с сервера. Первый содержит данные,а второй файл содержит контрольную сумму MD5-хэша.
Я создал функцию, которая возвращает hexdigest из файла данных следующим образом:
Я сравниваю файлы, используя следующее:
Сравнение файлов не удается, поэтому я распечатал оба fileHash и fileHandleData , и я получаю следующее:
Из выходных данных выше хэш-значения идентичны. Почему происходит сравнение хэшей потерпеть неудачу? Я новичок в python и использую python 3.2. Есть предложения?
Сравнение не удается по той же причине, что это ложно:
Формат этого файла. md5 странный, но если он всегда находится в этом формате, простой способ проверить будет:
Поскольку у вас есть файловый хэш в виде строки (Unicode), вы должны кодировать его в байты для сравнения. Вы можете указать кодировку, а не использовать текущую строковую кодировку по умолчанию.
Если этот точный формат всегда ожидается, было бы более надежным использовать регулярное выражение для извлечения значение хэша и, возможно, проверить имя файла.
Или, более гибко, вы можете проверить наличие подстроки:
Вы сравниваете хэш-значение с содержимым fileHandle . Вам нужно избавиться от части MD5 (hashFile.tbz) = , а также от завершающей новой строки, поэтому попробуйте:
Имейте в виду, что в Python 3, rsplit() и rstrip() не поддерживают API буфера и работают только со строками. Следовательно, Как правильно добавил Фред Нурк, вам также нужно кодировать / декодировать fileHandleData/fileHash (байтовый буфер или строку (Unicode) соответственно).
Хэш-значения идентичны, но строки-нет. Вам нужно получить шестнадцатеричное значение дайджеста, и вам нужно разобрать хэш из файла. Как только вы сделаете это, вы можете сравнить их для равенства.
Попробуйте "fileHash.полоса ("\n"). затем сравните их. Это должно решить проблему.
Есть 2 папки в них есть файлы и подпапки. Некоторые файлы совпадают по названию, но, возможно не совпадают по имени. Так же возможно есть файлы в одной или обоих подпапках, которые не встречаются в другой папке.
Нужно сравнить (по хэшу или как-то по-другому) все файлы в 2 папках и вложенных папках и узнать какие из файлов отличаются (и желательно какие из файлов не повторяются).
Есть ли ПО, которое может это сделать или bash скрипт или что-то подобное?
- Вопрос задан более года назад
- 223 просмотра
Простой 6 комментариев
Фокс Йовович,
точно, как я такое забыл.
да патамучта не пользовал
тру линуксоиды живут без бэкапа))) (дома)
Фокс Йовович, спасибо, посмотрю, а есть ли какие-нибудь альтернативы? Желательно кроссплатформенные или хотя бы для винды, потому что в gitbash, увы, нет rsync.
Drovosek01, я пару месяцев назад писал похожий скриптик: сравнивает сначала размер и дату, если они совпадают, тогда еще дополнительно сравнивает хэши. Но оно на на VBS и, соответственно, Windows-only.
под Windows : Total Commander, Unreal Commander, Double Commander
под Linux: Double Commander
функция - Команды - Синхронизировать каталоги (как-то так)
mc и far вроде так же умеют сравнивать каталоги.
скрипт лучше всего наверно написать на python (есть на любой ОС, хотя на любителя), взять за пример выше на VBS (честно не вчитывался) либо по своему написать, имхо - заносить хеши файлов в массив, затем сравнивать (ну как-то так)
на bash предполагаю будет жутким извращением, хотя думаю что возможно.
PS: в bash все равно не обойтись чистым bash, потребуется как минимум одна внешняя команда md5sum , которой в Windows скорее всего не будет и надо будет искать ее порт под Windows или аналог. Так же есть diff , который можно было бы использовать, но это опять же не встроенная в bash команда.
либо даже Cygwin со всеми соответствующими плюшками.
хотя, в Windows 10 есть целая подсистема Linux - WSL
ну для начала отфильтруй хотя бы по размеру,
потом уже, из меньшей кучи, сравнивай.
md5 быстро работает(man md5sum), если у тебя файлов не 100500 мильёнов )))
Насколько я знаю, эта команда вычисляет md5 для 1 переданного в нее файла или простого текста.
Вы предлагаете мне для каждого файла отдельно вычислять хэш, а потом еще самому сравнивать?
Drovosek01,
а как вы по другому представляете сравнение?
лишний пробел или таб = много значит(не везде конечо,
но тем не менее
на днях, я не мог закомпилить код, т.к. там(при копипасте, вместо табов , были пробелы
Нужно сравнить (по хэшу или как-то по-другому) все файлы с одинаковым именем в 2 папках и вложенных папках и узнать какие из файлов отличаются (и желательно какие из файлов не повторяются).
Предполагаю, что это будет происходить автоматически, а не я буду делать вручную для каждого файла отдельно.
Drovosek01,
в чём проблема то?
ты даже не пытался это решить
алгоритм тебе выдали
чего не понятно?
запустить в цикле ?
SOTVM, проблема в том, что файлов много.
Как для каждого отдельного файла находить хэш сумму я знаю, но вопрос в другом.
Если вам нравится работать руками, наверное вы не тот форум посещаете.
В чём преимущество в сравнении контрольных сумм, а не самих файлов, только если не контрольная сумма для одного из файлов известна заранее.
Читайте также: