Хеширование файла в Python
Я хочу, чтобы python читал EOF, поэтому я могу получить соответствующий хеш, будь то sha1 или md5. Пожалуйста помоги. Вот что я до сих пор:
import hashlib
inputFile = raw_input("Enter the name of the file:")
openedFile = open(inputFile)
readFile = openedFile.read()
md5Hash = hashlib.md5(readFile)
md5Hashed = md5Hash.hexdigest()
sha1Hash = hashlib.sha1(readFile)
sha1Hashed = sha1Hash.hexdigest()
print "File Name: %s" % inputFile
print "MD5: %r" % md5Hashed
print "SHA1: %r" % sha1Hashed
Ответы
Ответ 1
TL; DR используют буферы, чтобы не использовать тонны памяти.
Мы рассматриваем суть проблемы, я полагаю, когда мы рассматриваем влияние памяти на работу с очень большими файлами. Мы не хотим, чтобы этот плохой мальчик опрокинул 2 гигабайта барана для файла размером 2 гигабайта, так как pasztorpisti указывает, что мы должны иметь дело с этими большими файлами в кусках!
import sys
import hashlib
# BUF_SIZE is totally arbitrary, change for your app!
BUF_SIZE = 65536 # lets read stuff in 64kb chunks!
md5 = hashlib.md5()
sha1 = hashlib.sha1()
with open(sys.argv[1], 'rb') as f:
while True:
data = f.read(BUF_SIZE)
if not data:
break
md5.update(data)
sha1.update(data)
print("MD5: {0}".format(md5.hexdigest()))
print("SHA1: {0}".format(sha1.hexdigest()))
Что мы сделали, мы обновляем наши хэши этого плохого мальчика в кусках 64kb, когда мы соглашаемся с hashlib handy dandy метод обновления. Таким образом, мы используем намного меньше памяти, чем 2gb, которые потребовалось бы для хэширования парня сразу!
Вы можете проверить это с помощью:
$ mkfile 2g bigfile
$ python hashes.py bigfile
MD5: a981130cf2b7e09f4686dc273cf7187e
SHA1: 91d50642dd930e9542c39d36f0516d45f4e1af0d
$ md5 bigfile
MD5 (bigfile) = a981130cf2b7e09f4686dc273cf7187e
$ shasum bigfile
91d50642dd930e9542c39d36f0516d45f4e1af0d bigfile
Надеюсь, что это поможет!
Также все это изложено в связанном вопросе с правой стороны: Получить MD5-хэш больших файлов в Python
Добавление!
В целом при написании python это помогает привыкнуть следовать pep-8. Например, в переменных python обычно подчеркивается разделитель, а не camelCased. Но это просто стиль, и никто не заботится об этих вещах, кроме людей, которые должны читать плохой стиль..., возможно, вы читаете этот код через несколько лет.
Ответ 2
Для правильного и эффективного вычисления значения хеш-функции файла (в Python 3):
- Откройте файл в двоичном режиме (т.е. Добавьте
'b'
в файловый режим), чтобы избежать проблем с кодировкой символов и окончанием строки. - Не читайте весь файл в память, так как это пустая трата памяти. Вместо этого последовательно читайте его блок за блоком и обновляйте хэш для каждого блока.
- Устраните двойную буферизацию, т.е. не используйте буферизованный ввод-вывод, потому что мы уже используем оптимальный размер блока.
- Используйте
readinto()
чтобы избежать взбалтывания буфера.
Пример:
import hashlib
def sha256sum(filename):
h = hashlib.sha256()
b = bytearray(128*1024)
mv = memoryview(b)
with open(filename, 'rb', buffering=0) as f:
for n in iter(lambda : f.readinto(mv), 0):
h.update(mv[:n])
return h.hexdigest()
Ответ 3
Откройте файл в двоичном режиме, режим по умолчанию open()
- 'r'
, который "открыт для чтения в текстовом режиме". В текстовом режиме преобразование новой строки выполняется на ваши данные, это может также вызвать ошибки в конкретной платформе, но возможная проблема, которая может возникнуть в результате текстового режима, состоит в том, что последовательности "\ r\n" заменяются на последовательности "\n" в вы получите в свои руки. Не все файлы содержат последовательности "\ r\n", особенно в случае двоичных файлов, поэтому ошибка не будет появляться все время, и было бы сложно ее поймать.
openedFile = open(inputFile, 'rb')
Здесь есть еще одна небольшая проблема. Вы читаете файл в одном большом фрагменте, читая его в меньших количествах килобайтных фрагментов, вы сможете обрабатывать очень большие файлы, даже если они не будут вписываться в вашу доступную память.
Ответ 4
Я запрограммировал модуль, который может хэшировать большие файлы с разными алгоритмами.
pip3 install py_essentials
Используйте модуль так:
from py_essentials import hashing as hs
hash = hs.fileChecksum("path/to/the/file.txt", "sha256")
Ответ 5
import hashlib
user = input("Enter ")
h = hashlib.md5(user.encode())
h2 = h.hexdigest()
with open("encrypted.txt","w") as e:
print(h2,file=e)
with open("encrypted.txt","r") as e:
p = e.readline().strip()
print(p)
Ответ 6
Я бы предложил просто:
def get_digest(file_path):
h = hashlib.sha256()
with open(file_path, 'rb') as file:
while True:
# Reading is buffered, so we can read smaller chunks.
chunk = file.read(h.block_size)
if not chunk:
break
h.update(chunk)
return h.hexdigest()
Все остальные ответы здесь, кажется, слишком усложняют. Python уже буферизует при чтении (в идеальном случае, или вы настраиваете эту буферизацию, если у вас есть больше информации о базовом хранилище), и поэтому лучше читать в блоках, хэш-функция находит идеал, что делает его быстрее или, как минимум, менее интенсивным для ЦП, чтобы вычислить хэш-функцию. Поэтому вместо того, чтобы отключать буферизацию и пытаться эмулировать ее самостоятельно, вы используете буферизацию Python и управляете тем, что вы должны контролировать: что потребитель ваших данных находит идеальным, размер блока хеша.