Я хочу, чтобы 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
file.read()
делает - читать весь файл.read()
методу написано?Ответы:
TL; DR используйте буферы, чтобы не использовать тонны памяти.
Я считаю, что мы подходим к сути вашей проблемы, когда рассматриваем последствия для памяти при работе с очень большими файлами . Мы не хотим, чтобы этот плохой мальчик потратил 2 гигабайта оперативной памяти на 2-гигабайтный файл, поэтому, как указывает пасторписти , мы должны обрабатывать эти большие файлы кусками!
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()))
Что мы сделали, так это обновили наши хэши этого плохого парня кусками по 64 КБ, следуя удобному методу обновления hashlib . Таким образом, мы используем намного меньше памяти, чем 2 ГБ, которые потребовались бы для хеширования всего парня сразу!
Вы можете проверить это с помощью:
$ 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 переменные обычно разделяются подчеркиванием, а не верблюжьим регистром. Но это всего лишь стиль, и никого не волнуют эти вещи, кроме людей, которым приходится читать плохой стиль ... который, возможно, вы читаете этот код через годы.
источник
BUF_SIZE
?shasum
двоичные файлы. Другой ответ, указанный ниже (тот, который использует memoryview), совместим с другими инструментами хеширования.Для правильного и эффективного вычисления хеш-значения файла (в 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()
источник
resource.getpagesize
ли здесь какая-то польза, если мы хотим попытаться оптимизировать его несколько динамически? А чтоmmap
?Я бы просто предложил:
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 и контролируете то, что вы должны контролировать: то, что потребитель ваших данных считает идеальным, размер хэш-блока.
источник
hash.block_size
документируется так же, как «размер внутреннего блока алгоритма хеширования». Хашлиб не считает это идеальным . Ничто в документации пакета не предполагает, чтоupdate()
предпочитаетhash.block_size
размер ввода. Он не использует меньше процессора, если вы его так называете. Вашfile.read()
вызов приводит к созданию множества ненужных объектов и избыточных копий из файлового буфера в ваш новый объект байт фрагмента.block_size
частям. Если вы не предоставляете их в этих кусках, они должны буферизоваться и ждать появления достаточного количества данных или внутренне разбивать данные на куски. Итак, вы можете просто справиться с этим снаружи, а затем упростите то, что происходит внутри. Я считаю это идеальным. См., Например: stackoverflow.com/a/51335622/252025block_size
намного меньше любого полезного размера для чтения. Кроме того, любые полезные размеры блока и чтения - это степени двойки. Таким образом, размер чтения делится на размер блока для всех операций чтения, кроме, возможно, последнего. Например, размер блока sha256 составляет 64 байта. Это означает, чтоupdate()
он может напрямую обрабатывать ввод без какой-либо буферизации, кратнойblock_size
. Таким образом, только если последнее чтение не делится на размер блока, он должен буферизовать до 63 байтов один раз. Следовательно, ваш последний комментарий неверен и не поддерживает утверждения, которые вы делаете в своем ответе.Я запрограммировал модуль, который может хешировать большие файлы с помощью разных алгоритмов.
Используйте модуль следующим образом:
from py_essentials import hashing as hs hash = hs.fileChecksum("path/to/the/file.txt", "sha256")
источник
Вот решение Python 3, POSIX (не Windows!), Которое используется
mmap
для отображения объекта в память.import hashlib import mmap def sha256sum(filename): h = hashlib.sha256() with open(filename, 'rb') as f: with mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) as mm: h.update(mm) return h.hexdigest()
источник
mmap
в этом сценарии?bytes
объекты в памяти и вызываютread
слишком много или слишком мало раз. Это отобразит файл непосредственно в виртуальную память и хэширует его оттуда - операционная система может отобразить содержимое файла непосредственно из буферного кеша в процесс чтения. Это означает, что это может быть во много раз быстрее, чем это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)
источник
echo $USER_INPUT | md5sum > encrypted.txt && cat encrypted.txt
что не касается хеширования файлов, особенно больших.