2017-06-28 2 views
1

J'écris un programme Python pour trouver des fichiers en double. Le calcul de MD5 et la comparaison de taille de fichier ne sont pas infaillibles à 100% car il est possible que deux fichiers différents aient la même taille de fichier et MD5 (probabilité de collision 2^128). Je me demandais alors, peut-être si j'ajoute un autre hachage comme SHA1 (2^160) ou CRC32 (2^32) au mélange, cela augmenterait considérablement la capacité d'identifier des fichiers uniques, à savoir comparer MD5 et MD5. SHA1 d'un fichier pour l'unicité? Est-ce que SHA1 ou CRC32 est préférable pour cette vérification secondaire?Calculer MD5 et SHA1 simultanément sur un gros fichier

Si oui, comment puis-je calculer à la fois MD5 et SHA1/CRC32 simultanément lors de l'itération de blocs de 1 Mo d'un très gros fichier pour éviter de lire le gros fichier deux fois? Voilà ce que j'ai pour MD5:

def md5(fname): 
    hash_md5 = hashlib.md5() 
    with open(fname, "rb") as f: 
     for chunk in iter(lambda: f.read(2 ** 20), b""): 
      hash_md5.update(chunk) 
    return hash_md5.hexdigest() 

Actuellement mon code, après vérification MD5 identiques de, courraient filecmp.cmp sur les deux dossiers que le contrôle final. C'est évidemment une ressource intensive et pas efficace. J'utilise SQLite pour stocker ces hachages. Je suppose qu'il est plus lent que les listes Python mais ne souffre pas d'une mémoire insuffisante lors du traitement de milliards de fichiers.

+0

2^128 est trompeur, mais la probabilité réelle d'une collision est assez petit que vous ne devez pas vous inquiéter, MD5 est très bien (pour non applications sensibles) https://stackoverflow.com/questions/4032209/is-md5-still-good-enough-to-uni-ly-identify-files/https://crypto.stackexchange.com/questions/12677/strength-of -md5-in-finding-duplicate-files/12679 –

+0

Merci pour le commentaire. La probabilité "assez faible" ne suffira pas à quelqu'un avec 500 + Go d'images photo pour trier et éliminer les doublons. Vous vous demandez si SHA1/CRC32 est suffisant pour "garantir" cela. Peut-être que filecmp.cmp est le seul moyen infaillible ... – ebann

+0

Utilisation de deux fonctions de hachage devrait vous donner assez de certitude pour dormir paisiblement;) – Maciek

Répondre

2

Vous avez déjà la partie la plus difficile. Il suffit de nourrir les morceaux que vous lisez à un autre Hasher:

def calculate_hashes(fname): 
    hash_md5 = hashlib.md5() 
    hash_sha1 = hashlib.sha1() 
    with open(fname, "rb") as f: 
     for chunk in iter(lambda: f.read(2 ** 20), b""): 
      hash_md5.update(chunk) 
      hash_sha1.update(chunk) 
    return hash_md5.hexdigest(), hash_sha1.hexdigest() 
+0

Merci pour l'extrait de code! L'implémentera et chronométrera les résultats pour voir comment il se compare avec l'utilisation de filecmp.cmp. Devrait être beaucoup plus rapide ... – ebann