Il y a une façon qui est assez mémorable inefficace .
fichier unique :
import hashlib
def file_as_bytes(file):
with file:
return file.read()
print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()
liste de fichiers :
[(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Rappelons toutefois que MD5 est connu pour être cassé et ne devrait pas être utilisé à quelque fin que ce soit, car l'analyse des vulnérabilités peut être vraiment délicate, et l'analyse de toute utilisation future possible de votre code pour des questions de sécurité est impossible. IMHO, il devrait être carrément retiré de la bibliothèque afin que tous ceux qui l'utilisent soient obligés de le mettre à jour. Voici donc ce que vous devriez faire à la place :
[(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]
Si vous voulez seulement 128 bits de résumé, vous pouvez faire .digest()[:16]
.
Cela vous donnera une liste de tuples, chaque tuple contenant le nom de son fichier et son hachage.
Encore une fois, je remets fortement en question votre utilisation du MD5. Vous devriez au moins utiliser SHA1, et étant donné failles récentes découvertes dans SHA1 et probablement même pas. Certaines personnes pensent que tant que vous n'utilisez pas MD5 à des fins "cryptographiques", tout va bien. Mais les choses ont tendance à avoir une portée plus large que ce à quoi vous vous attendiez initialement, et votre analyse de vulnérabilité occasionnelle peut s'avérer complètement erronée. Il est préférable de prendre l'habitude d'utiliser le bon algorithme dès le départ. Il s'agit simplement de taper un autre groupe de lettres. Ce n'est pas si difficile.
Voici une méthode plus complexe, mais Mémoire efficace :
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]
Et, encore une fois, puisque MD5 est cassé et ne devrait plus jamais être utilisé :
[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
for fname in fnamelst]
Encore une fois, vous pouvez mettre [:16]
après l'appel à hash_bytestr_iter(...)
si vous ne voulez que 128 bits de condensé.
3 votes
Pourquoi ne pas simplement utiliser
md5sum
?108 votes
Le fait de le garder en Python facilite la gestion de la compatibilité multiplateforme.
0 votes
Si vous voulez une solution avec "barre de progression* ou similaire (pour les très gros fichiers), considérez cette solution : stackoverflow.com/questions/1131220/
1 votes
@kennytm Le lien que vous avez fourni dit ceci dans le deuxième paragraphe : "L'algorithme MD5 sous-jacent n'est plus considéré comme sûr" tout en décrivant
md5sum
. C'est pourquoi les programmeurs soucieux de la sécurité ne devraient pas l'utiliser, à mon avis.1 votes
@Debug255 Bon point et valable. Les deux
md5sum
et la technique décrite dans cette question SO doit être évitée - il est préférable d'utiliser SHA-2 ou SHA-3, si possible : fr.wikipedia.org/wiki/Secure_Hash_Algorithms0 votes
@PerLundberg ou le plus récent
hashlib.blake2b
qui est à la fois plus rapide que md5 et sécurisé.0 votes
@Boris Merci. BLAKE2b/BLAKE2s est-il aussi largement disponible sur toutes les plates-formes que les algorithmes SHA ? (Je n'en avais pas entendu parler avant que vous ne les mentionniez ici).
0 votes
@PerLundberg les langages modernes devraient les implémenter (je sais que Python, Go et Rust le font). Il existe un
b2sum
disponible sur Ubuntu.0 votes
OK, bien. Pour référence : crypto.stackexchange.com/questions/45127/
0 votes
Il peut être utile de mentionner qu'il existe encore des raisons valables d'utiliser le format md5 qui ne sont pas affectées par sa défaillance à des fins de sécurité. (par exemple, la vérification de la pourriture des bits dans un système qui utilise la création de md5 intégrée pendant l'archivage).