IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Repérer deux fichiers identiques mais pas avec les mêmes dates


Sujet :

Python

  1. #1
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut Repérer deux fichiers identiques mais pas avec les mêmes dates
    Bonjour,
    j'ai deux fichiers Fichier1.png et Fichier2.png. Je voudrais savoir si ces fichiers sont identiques mais s'en tenir compte de leurs dates de modification, de création.
    La méthode doit pouvoir marcher avec tout type de fichier.

    Toute info. est la bienvenue.

  2. #2
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Soit tu ouvres les fichiers en mode binaire et tu compares bit à bit (et c'est un peu lourd).
    Soit tu géneres un hash de tes fichiers et si ils sont égaux, tes fichiers sont identiques.
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  3. #3
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci pour la réponse.
    La comparaison bits à bits était-elle lente ou juste pénible à mettre en oeuvre ?

    Pour le hash cela me parait simple dans l'esprit. Va falloir que je regarde cela de prêt.

    Une fois quelque chose qui fonctionne à peu près je poste ici.

  4. #4
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Je dirais que le mecanisme de hashage est adapté à cette problématique.
    Tu peux ainsi conserver une empreinte de ton fichier pour savoir si il a été modifié.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import hashlib
    f = open('text1.txt', 'rb')
    hash = hashlib.sha1()
    data = f.read(1024)
    while data:
        hash.update(data)
        data = f.read(1024)
     
    print hash.hexdigest()
     
    # en plus court pour un petit fichier
    print hashlib.sha1(open('text1.txt', 'rb').read()).hexdigest()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f52a7c8f14cc9dbf64ed942d2d66a45ef3e5695b
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci,quézako ce read(1024) ?

  6. #6
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    help(file.read)
     
    read(...)
        read([size]) -> read at most size bytes, returned as a string.
     
        If the size argument is negative or omitted, read until EOF is reached.
        Notice that when in non-blocking mode, less data than what was requested
        may be returned, even if no size parameter was given.
    Cela permet de lire une partie de ton fichier (içi 1024 octets) sans le charger entiérement en mémoire.
    Si tu veux faire un hash sur un fichier de plusieurs méga, il vaut mieux éviter de charger l'integralité de celui-ci en mémoire.
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  7. #7
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci pour ces infos.

    Sur ce je vais aller travailler.

  8. #8
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Pour la comparaison des contenus bit à bit, voici une proposition:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    import os
     
    def compfichiers(nf1, nf2, lgbuf=32*1024):
        """Compare les 2 fichiers et renvoie True seulement s'ils ont un contenu identique"""
        f1 = f2 = None
        try:
            result = False
            # si leur longueur est différente, renvoie False
            if os.path.getsize(nf1)!=os.path.getsize(nf2):
                return result
            # compare les contenus
            f1 = open(nf1, "rb")
            f2 = open(nf2, "rb")
            while True:
                buf1 = f1.read(lgbuf)
                if len(buf1)==0:
                    result = True
                    break
                buf2 = f2.read(lgbuf)
                if buf1!=buf2:
                    break
            f1.close()
            f2.close()
        except:
            if f1!=None:
                f1.close()
            if f2!=None:
                f2.close()
            raise IOError
        return result
    Les 2 arguments doivent être des noms de fichiers complets avec leur chemin.

    Je n'ai pas essayé, mais a priori, le code devrait être multiplateforme.

    Cette fonction renvoie 3 résultats possibles:

    • True si les contenus sont identiques

    • False s'ils ne le sont pas

    • Une exception si une erreur est intervenue (ouverture, lecture, fermeture)


    Voilà comment on y fait appel dans ces 3 cas possibles:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    if __name__ == "__main__":
     
        import time
     
        # 1er cas: les 2 fichiers sont identiques 
        nf1 = r"C:\Python25\DLLs\tk84.dll"
        nf2 = r"C:\Python25\DLLs\tk84_idem.dll"
        try:
            t = time.clock()
            result = compfichiers(nf1, nf2)
            t = time.clock()-t
            print u"Résultat:", result, "%.3f s" % t
        except:
            t = time.clock()-t
            print u"Résultat: Erreur", "%.3f s" % t
     
     
        # 2ème cas: les 2 fichiers sont différents 
        nf1 = r"C:\Python25\DLLs\tk84.dll"
        nf2 = r"C:\Python25\DLLs\unicodedata.pyd"
        try:
            t = time.clock()
            result = compfichiers(nf1, nf2)
            t = time.clock()-t
            print u"Résultat:", result, "%.3f s" % t
        except:
            t = time.clock()-t
            print u"Résultat: Erreur", "%.3f s" % t
     
        # 3ème cas: le second fichier n'existe pas
        nf1 = r"C:\Python25\DLLs\tk84.dll"
        nf2 = r"C:\Python25\DLLs\cefichiernexistepas.$$$"
        try:
            t = time.clock()
            result = compfichiers(nf1, nf2)
            t = time.clock()-t
            print u"Résultat:", result, "%.3f s" % t
        except:
            t = time.clock()-t
            print u"Résultat: Erreur", "%.3f s" % t
    Et voilà les résultats avec les durées d'exécution en secondes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Résultat: True 0.004 s
    Résultat: False 0.000 s
    Résultat: Erreur 0.000 s
    Une fois que la fonction est au point, le résultat est renvoyé très rapidement, le plus lent étant la comparaison entre 2 fichiers identiques (c'est normal: il faut tout lire!). Mais ici, on a obtenu le résultat "True" en 4 millisecondes avec 2 fichiers identiques d'1Mo chacun.

    Avec des fichiers beaucoup plus gros, ça se gâte un peu: avec 4.24Go (c'est l'image iso d'un DVD linux), la réponse demande 3 minutes. Le hashage ne semble pas plus rapide. En effet, il faut tout de même lire les 2 fichiers! De plus, comme il faut lire complètement les 2 fichiers avant de comparer les 2 hash, la durée n'est pas diminuée quand les 2 fichiers diffèrent dès le 1er octet. J'ai essayé le calcul du MD5 des mêmes 2 fichiers: cela m'a demandé plus de 4 minutes.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  9. #9
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    Citation Envoyé par pacificator Voir le message
    ...Soit tu géneres un hash de tes fichiers et si ils sont égaux, tes fichiers sont identiques.
    Rien ne garantie que 2 fichiers produisant la même empreinte (hash) soient identiques, c'est ce qu'on appelle les collisions.
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  10. #10
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Citation Envoyé par DelphiManiac Voir le message
    Rien ne garantie que 2 fichiers produisant la même empreinte (hash) soient identiques, c'est ce qu'on appelle les collisions.
    Je suis d'accord, c'est pourquoi j'ai utilisé sha1 qui est beaucoup moins sujet aux collisions que md5
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Certes, mais statistiquement il y a une collision entre 2 fichiers de taille inférieure ou égale à 20 octets.
    En effet, sha1 génère des hash de 20 octets (40 digits hexa), soit 256**20 hash différents. Donc, si on suppose que la première collision intervient après toutes les combinaisons possibles (au sens de l'ordre lexicographique), on a toutes les combinaisons en utilisant des fichiers de taille inférieure ou égale à 20 octets. (il y en a exactement (256**21 - 1)/255 soit "un peu" (5.7*10**45 par rapport à 10**49) plus que 256**20)

  12. #12
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    J'ai fais cette remarque, parce que, vu la demande initiale, il n'est pas acceptable, même avec une probabilité très faible de considérer deux fichiers identiques s'il ne le sont pas.

    Surtout comme l'a fait remarqué un intervenant, pour calculer un hash, il faut dans tout les cas, lire le fichier entièrement, donc autant comparer "bit à bit", au moins on peut arrêter la comparaison dès la première différence, on y gagnera souvent.
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  13. #13
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Je suis tout-à-fait d'accord avec toi DelphiManiac, c'est à l'argument de pacificator que je répondais. Que ce soit MD5 ou SHA-1, statistiquement la limite de "non-collision" passe de 16 à 20 octets, ce qui ne représente rien compte tenu des tailles moyennes des fichiers.

  14. #14
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci tyrtamos pour le code !


    Citation Envoyé par DelphiManiac Voir le message
    J'ai fais cette remarque, parce que, vu la demande initiale, il n'est pas acceptable, même avec une probabilité très faible de considérer deux fichiers identiques s'il ne le sont pas.
    Tout à fait. Mais le code de hashage me sera utile pour d'autres situations. Donc comme toujours toute remarque est la bienvenue.

    Merci à tous pour les commentaires instructifs.

  15. #15
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Très intéressant. Réponses toutes cuites à des questions que je n'ai même pas eues à poser. Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 12/04/2011, 17h30
  2. Réponses: 5
    Dernier message: 14/12/2009, 09h36
  3. Réponses: 7
    Dernier message: 09/12/2008, 00h28
  4. Réponses: 7
    Dernier message: 19/02/2008, 15h30
  5. Réponses: 1
    Dernier message: 09/10/2007, 06h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo