Page 1 sur 1

Hash rapide

Publié : mer. 29/août/2012 21:57
par Droopy
Juste un petit code pour hasher un fichier rapidement.
Peut permettre de trouver rapidement des fichiers identiques :wink:

Code : Tout sélectionner

Procedure.s FastHash(file.s,Sample=3,SampleSize=1048576)
  
  ;/ Default = hash @ 1/3 1/2 2/3 with sample of 1Mb
  
  Size.q=FileSize(file)
  
  If Size>Size/(Sample+1)*Sample+SampleSize; Check buffer size
    fid=ReadFile(#PB_Any,file)
    If fid
      *buffer=AllocateMemory(SampleSize)
      
      For n=1 To Sample
        ;/ Hash the Sample
        FileSeek(fid,Size/(Sample+1)*n)
        ReadData(fid,*buffer,SampleSize)
        Hash.s+MD5Fingerprint(*buffer,SampleSize)
      Next

      ;/ Add file size to hash
      Hash+Str(Size)
       
      ;/ free buffer & file
      FreeMemory(*buffer)
      CloseFile(fid)
      
      ProcedureReturn MD5Fingerprint(@Hash,Len(Hash))
    EndIf
  EndIf
  
EndProcedure

fichier.s="Z:\yyyyyyy.avi"

start=ElapsedMilliseconds()
Fast$ = "FastHash "+FastHash(fichier)+" en "+Str(ElapsedMilliseconds()-start)+" ms"

start=ElapsedMilliseconds()
Md5$ = "MD5 "+MD5FileFingerprint(fichier)+ " en "+Str(ElapsedMilliseconds()-start)+" ms"

MessageRequester("Resultat", Fast$ + Chr(10) + Md5$, 0)

Re: Hash rapide

Publié : mer. 29/août/2012 22:14
par Ar-S
Très efficace ! Merci !

Note : Tu pourrais modifier la fin de ton code pour un résultat "plus vrai" sans le debug

Code : Tout sélectionner

start=ElapsedMilliseconds()
Fast$ = "FastHash "+FastHash(fichier)+" en "+Str(ElapsedMilliseconds()-start)+" ms"

start=ElapsedMilliseconds()
Md5$ = "MD5 "+MD5FileFingerprint(fichier)+ " en "+Str(ElapsedMilliseconds()-start)+" ms"

MessageRequester("Resultat", Fast$ + Chr(10) + Md5$, 0)

Re: Hash rapide

Publié : mer. 29/août/2012 22:49
par Droopy
Exemple modifié, erci Ar-S.

Re: Hash rapide

Publié : mer. 29/août/2012 23:33
par Ar-S
Vu son efficacité, tu m'autorises à faire un vérificateur de fichier (comme mon MD5 File Validator ?) utilisant ton algo ?

Re: Hash rapide

Publié : mer. 29/août/2012 23:49
par Droopy
Algo modifié : Choix du nombre d'échantillons.
Ar-S a écrit :Vu son efficacité, tu m'autorises à faire un vérificateur de fichier (comme mon MD5 File Validator ?) utilisant ton algo ?
Bien entendu.

Re: Hash rapide

Publié : jeu. 30/août/2012 8:37
par Droopy
Code modifié : Ajout de la taille du fichier dans le calcul du hash

Re: Hash rapide

Publié : jeu. 30/août/2012 9:43
par Ar-S
En gros ce fasthash prend 1, 2 ou 3 morceaux de 1mo d'un plus gros fichier et calcul un hash unique avec ces 3 bouts ?

Re: Hash rapide

Publié : jeu. 30/août/2012 10:32
par Droopy
Ar-S a écrit :En gros ce fasthash prend 1, 2 ou 3 morceaux de 1mo d'un plus gros fichier et calcul un hash unique avec ces 3 bouts ?
C'est ça, tu as tout compris.

Si FastHash trouve 2 hash identiques, MD5 peut être utilisé lors d'une 2° phase afin de s'assurer qu'ils le sont réllement.
Le gain de temps devrait être appréciable.

Re: Hash rapide

Publié : jeu. 30/août/2012 11:01
par Ar-S
Je n'ai compris comment il se comporte avec des fichiers plus petit qu'1 mo. (j'ai vu que ça marche mais j'aimerai piger).

Un petit truc me chiffonne mais ce n'est pas de ta faute, c'est la commande MD5FileFingerprint() à laquelle il manque un retour de message d'erreur (hors debug) si le fichier est inexistant.

Ton exemple le prouve d'ailleurs avec fichier.s="Z:\yyyyyyy.avi"

Donc faudrait ajouter une petite vérif dans le code principale.

Code : Tout sélectionner

fichier.s="Z:\yyyyyyy.avi"

Verif.q = FileSize(fichier)
If Verif > 0
  
  start=ElapsedMilliseconds()
  Fast$ = "FastHash "+FastHash(fichier)+" en "+Str(ElapsedMilliseconds()-start)+" ms"
  
  start=ElapsedMilliseconds()
  Md5$ = "MD5 "+MD5FileFingerprint(fichier)+ " en "+Str(ElapsedMilliseconds()-start)+" ms"
  
  MessageRequester("Resultat", Fast$ + Chr(10) + Md5$, 0)
  
Else
  
  MessageRequester("Erreur","Le fichier est introuvable !",#MB_OK|#MB_ICONEXCLAMATION)
  
EndIf

Re: Hash rapide

Publié : jeu. 30/août/2012 20:10
par Droopy
Je teste si la taille de l'échantillon est adaptée à la taille du fichier.
En effet sur un fichier de 1mo, on ne peut pas lire 3 bandes de 1mo à respectivement 1/3 1/2 2/3.
Dans ce cas la fonction renvoie une chaine vide (signe d'erreur)
La présence du fichier est donc testée indirectement.

Re: Hash rapide

Publié : jeu. 30/août/2012 20:54
par G-Rom
merci Droopy.

Re: Hash rapide

Publié : ven. 31/août/2012 12:51
par Kwai chang caine
Cool pour des doublons de photos avec un nom different :D
Merci DROOPY 8)

Re: Hash rapide

Publié : ven. 31/août/2012 13:57
par MLD
Salut KCC
Heureux de te lire sur ce Fofo.

Re: Hash rapide

Publié : ven. 31/août/2012 17:21
par Kwai chang caine
Merci mon grand :wink: