Pour référence, voici une version plus concise:
def sha1OfFile(filepath):
import hashlib
with open(filepath, 'rb') as f:
return hashlib.sha1(f.read()).hexdigest()
Après réflexion : bien que je ne l'aie jamais vu, je pense qu'il y a un potentiel pour que f.read()
renvoie moins que le fichier complet, ou pour un fichier de plusieurs gigaoctets, que f.read() manque de mémoire. Pour l'édification de tous, réfléchissons à la façon de corriger cela: Une première correction serait :
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
for line in f:
sha.update(line)
return sha.hexdigest()
Cependant, rien ne garantit que '\n'
apparaisse dans le fichier, donc le fait que la boucle for
nous donne des blocs de fichier se finissant par '\n'
pourrait nous poser le même problème qu'au départ. Malheureusement, je ne vois pas de moyen aussi Pythonique d'itérer sur des blocs de fichier aussi volumineux que possible, ce qui signifie, je pense, que nous sommes bloqués avec une boucle while True : ... break
et avec un nombre magique pour la taille du bloc :
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
while True:
block = f.read(2**10) # Nombre magique : blocs d'un mégaoctet.
if not block: break
sha.update(block)
return sha.hexdigest()
Bien sûr, qui pourrait dire que nous pouvons stocker des chaînes d'un mégaoctet. Nous le pouvons probablement, mais que se passe-t-il si nous sommes sur un petit ordinateur embarqué ?
J'aimerais pouvoir penser à une manière plus propre garantie de ne pas manquer de mémoire sur des fichiers énormes et qui n'a pas de nombres magiques et qui fonctionne aussi bien que la solution simple Pythonique originale.