Є спосіб, який досить неефективний у пам’яті .
один файл:
import hashlib
def file_as_bytes(file):
with file:
return file.read()
print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()
список файлів:
[(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Нагадаємо, що, як відомо , MD5 зламаний, і його не слід використовувати з будь-якою метою, оскільки аналіз вразливості може бути справді складним, а аналіз будь-якого можливого подальшого використання вашого коду може бути застосований для проблем безпеки неможливо. IMHO, його слід вилучити з бібліотеки, тому кожен, хто ним користується, змушений оновлюватись. Отже, ось що вам слід зробити замість цього:
[(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Якщо ви хочете переконати лише 128 біт, можна зробити .digest()[:16]
.
Це дасть вам список кортежів, кожен кортеж містить ім'я свого файлу та його хеш.
Знову я сильно ставлю під сумнів ваше використання MD5. Ви повинні хоча б використовувати SHA1, а враховуючи останні недоліки, виявлені в SHA1 , ймовірно, навіть не це. Деякі люди думають, що поки ви не використовуєте MD5 для «криптографічних» цілей, у вас все добре. Але речі мають тенденцію в кінцевому підсумку бути ширшими, ніж ви спочатку очікували, і ваш випадковий аналіз вразливості може виявитися повністю помилковим. Найкраще просто звикнути правильний алгоритм поза воротами. Це просто набрати іншу купу букв. Це не так складно.
Ось спосіб, який є більш складним, але ефективним для пам’яті :
import hashlib
def hash_bytestr_iter(bytesiter, hasher, ashexstr=False):
for block in bytesiter:
hasher.update(block)
return hasher.hexdigest() if ashexstr else hasher.digest()
def file_as_blockiter(afile, blocksize=65536):
with afile:
block = afile.read(blocksize)
while len(block) > 0:
yield block
block = afile.read(blocksize)
[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.md5()))
for fname in fnamelst]
І, знову ж таки, оскільки MD5 зламаний і його більше ніколи не слід використовувати:
[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
for fname in fnamelst]
Знову ж таки, ви можете [:16]
подзвонити після виклику, hash_bytestr_iter(...)
якщо ви хочете переварити лише 128 біт.
md5sum
?