Para referencia, aquí es una versión más concisa:
def sha1OfFile(filepath):
import hashlib
with open(filepath, 'rb') as f:
return hashlib.sha1(f.read()).hexdigest()
Pensándolo bien: aunque nunca he visto, Creo que existe la posibilidad de que f.read()
devuelva menos que el archivo completo, o para un archivo de muchos gigabytes, para que f.read() se quede sin memoria. Para la edificación de todos, vamos a considerar cómo arreglar eso: Una primera solución a eso es:
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
for line in f:
sha.update(line)
return sha.hexdigest()
Sin embargo, no hay garantía de que '\n'
aparece en el archivo en absoluto, por lo que el hecho de que el bucle for
nos dará bloques del archivo que termina en '\n'
podría darnos el mismo problema que teníamos originalmente. Tristemente, no veo ninguna forma similar de Pythonic de iterar sobre bloques del archivo lo más grande posible, lo que, creo, significa que estamos atrapados con un bucle while True: ... break
y con un número mágico para el tamaño de bloque:
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
while True:
block = f.read(2**10) # Magic number: one-megabyte blocks.
if not block: break
sha.update(block)
return sha.hexdigest()
Por supuesto, ¿quién puede decir que podemos almacenar cadenas de un megabyte. Probablemente podamos, pero ¿y si estamos en una pequeña computadora embebida?
Me gustaría poder pensar en una forma más limpia que garantice que no se quede sin memoria en archivos enormes y que no tenga números mágicos y que funcione tan bien como la solución original simple de Pythonic.
No puede ignorar la diferencia si planea usar los hashes juntos. –
Olvidé mencionar, solo usé git como referencia, no voy a usarlos juntos. – Ikke
Si el archivo puede ser bastante grande, puede procesarlo un bloque a la vez para que no lo necesite todo en la RAM de una vez: http://stackoverflow.com/questions/7829499/using-hashlib-to- compute-md5-digest-of-a-file-in-python3 – rakslice