Я использовал hashlib (который заменяет md5 в Python 2.6 / 3.0), и он работал нормально, если я открыл файл и поместил его содержимое в hashlib.md5()
функцию.
Проблема с очень большими файлами, размер которых может превышать размер оперативной памяти.
Как получить MD5-хеш файла без загрузки всего файла в память?
Ответы:
Разбейте файл на 8192-байтовые куски (или другие кратные 128 байтам) и последовательно подайте их в MD5
update()
.Это использует тот факт, что MD5 имеет 128-байтовые блоки дайджеста (8192 - 128 × 64). Поскольку вы не читаете весь файл в память, он не будет использовать намного больше, чем 8192 байта памяти.
В Python 3.8+ вы можете сделать
источник
hashlib.blake2b
вместоmd5
. В отличие от MD5, BLAKE2 безопасен, и он еще быстрее.Вам нужно прочитать файл кусками подходящего размера:
ПРИМЕЧАНИЕ. Убедитесь, что вы открыли свой файл с помощью 'rb', иначе вы получите неправильный результат.
Таким образом, чтобы сделать все в одном методе - используйте что-то вроде:
Вышеупомянутое обновление было основано на комментариях, предоставленных Frerich Raabe - и я проверил это и нашел, что это правильно на моей установке Windows Python 2.7.2
Я перепроверил результаты, используя инструмент «jacksum».
http://www.jonelo.de/java/jacksum/
источник
rb
вopen
функцию.hexdigest
вместо негоdigest
даст шестнадцатеричный хеш, который «выглядит» как большинство примеров хешей.if len(data) < block_size: break
?open
всегда открывает новый дескриптор файла с позицией, установленной на начало файла (если вы не открываете файл для добавления).Ниже я включил предложение из комментариев. Спасибо всем!
питон <3,7
Python 3.8 и выше
оригинальный пост
если вам нужен более питонический (без 'True') способ чтения файла, проверьте этот код:
Обратите внимание, что для функции iter () требуется пустая строка байтов, чтобы возвращаемый итератор остановился на EOF, поскольку read () возвращает b '' (а не просто '').
источник
128*md5.block_size
вместо8192
.md5.block_size
.b''
синтаксис был для меня новым. Объяснил здесь .Вот моя версия метода @Piotr Czapla:
источник
Используя несколько комментариев / ответов в этой теме, вот мое решение:
И наконец,
- Это было создано сообществом, спасибо всем за ваши советы / идеи.
источник
Портативное решение Python 2/3
Чтобы вычислить контрольную сумму (md5, sha1 и т. Д.), Вы должны открыть файл в двоичном режиме, потому что вы суммируете байтовые значения:
Чтобы быть переносимым py27 / py3, вы должны использовать
io
пакеты, например так:Если ваши файлы большие, вы можете предпочесть чтение файла по частям, чтобы избежать хранения всего содержимого файла в памяти:
Хитрость здесь в том, чтобы использовать
iter()
функцию с часовым (пустая строка).Если ваши файлы действительно большие, вам также может понадобиться отобразить информацию о прогрессе. Вы можете сделать это, вызвав функцию обратного вызова, которая печатает или записывает количество вычисленных байтов:
источник
Ремикс кода Bastien Semene, который учитывает комментарии Hawkwing о универсальной хеширующей функции ...
источник
Вы не можете получить его MD5 без чтения полного содержания. но вы можете использовать функцию обновления, чтобы прочитать содержимое файла блок за блоком.
m.update (а); m.update (b) эквивалентно m.update (a + b)
источник
Я думаю, что следующий код более питонический:
источник
Реализация принятого ответа для Django:
источник
Я не люблю петли. Основано на @Nathan Feger:
источник
hashlib
API не очень хорошо работает с остальной частью Python. Например, давайте возьмем то,shutil.copyfileobj
что близко не работает. Моей следующей идеей былоfold
(иначеreduce
) объединение итерируемых элементов в единые объекты. Например, хэш.hashlib
не предоставляет операторов, что делает это немного громоздким. Тем не менее складывали здесь иероглифы.источник
Я не уверен, что здесь не так много суеты. Недавно у меня были проблемы с md5 и файлами, хранящимися как двоичные объекты на MySQL, поэтому я экспериментировал с файлами разных размеров и простым подходом Python, а именно:
Я не обнаружил заметной разницы в производительности с диапазоном размеров файлов от 2 КБ до 20 МБ и, следовательно, нет необходимости «разбивать» хэширование. В любом случае, если Linux должен перейти на диск, он, вероятно, сделает это по крайней мере так же, как способность обычного программиста удержать его от этого. Как оказалось, проблема не была связана с md5. Если вы используете MySQL, не забудьте, что функции md5 () и sha1 () уже есть.
источник