Hay una manera que es bastante ineficiente de memoria .
archivo único:
import hashlib
def file_as_bytes(file):
with file:
return file.read()
print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()
lista de archivos:
[(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Recordemos, sin embargo, que MD5 se sabe roto y no debe ser utilizado para cualquier propósito ya que el análisis de la vulnerabilidad puede ser muy difícil, y el análisis de cualquier posible uso futuro de su código podría ser condenado a las cuestiones de seguridad es imposible. En mi humilde opinión, debe eliminarse completamente de la biblioteca para que todos los que lo usen se vean obligados a actualizar. Entonces, esto es lo que debes hacer en su lugar:
[(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Si solo quieres 128 bits de digestión, puedes hacerlo .digest()[:16]
.
Esto le dará una lista de tuplas, cada tupla contiene el nombre de su archivo y su hash.
Nuevamente, cuestiono mucho su uso de MD5. Al menos debería usar SHA1, y dados los defectos recientes descubiertos en SHA1 , probablemente ni siquiera eso. Algunas personas piensan que mientras no esté usando MD5 para propósitos 'criptográficos', está bien. Pero las cosas tienden a tener un alcance más amplio de lo que inicialmente esperaba, y su análisis de vulnerabilidad casual puede resultar completamente defectuoso. Es mejor acostumbrarse a usar el algoritmo correcto desde el principio. Simplemente escribir un grupo diferente de letras es todo. No es tan dificil.
Aquí hay una manera que es más compleja, pero eficiente en memoria :
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]
Y, de nuevo, dado que MD5 está roto y ya no debería usarse nunca más:
[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
for fname in fnamelst]
Una vez más, puede poner [:16]
después de la llamada a hash_bytestr_iter(...)
si solo desea un resumen de 128 bits.
md5sum
?