2014-06-24 15 views
5

Ho bisogno di una funzione di copia intelligente per la copia di file affidabile e veloce & collegamento. I file sono molto grandi (da alcuni gigabyte a oltre 200 GB) e distribuiti su molte cartelle con persone che rinominano i file e forse le cartelle durante il giorno, quindi voglio usare gli hash per vedere se ho già copiato un file, magari sotto un nome diverso, e solo creare un collegamento in quel caso.Questa funzione "hash veloce" è pericolosa?

Im completamente nuovo per l'hashing e sto usando questa funzione qui per hash:

import hashlib 

def calculate_sha256(cls, file_path, chunk_size=2 ** 10): 
    ''' 
    Calculate the Sha256 for a given file. 

    @param file_path: The file_path including the file name. 
    @param chunk_size: The chunk size to allow reading of large files. 
    @return Sha256 sum for the given file. 
    ''' 
    sha256 = hashlib.sha256() 
    with open(file_path, mode="rb") as f: 
     for i in xrange(0,16): 
      chunk = f.read(chunk_size) 
      if not chunk: 
       break 
      sha256.update(chunk) 
    return sha256.hexdigest() 

Questo prende un minuto per un file di 3GB, quindi alla fine, il processo potrebbe essere molto lento per un 16TB HD.

Ora la mia idea è di usare qualche conoscenza aggiuntiva sulla struttura interna dei file per accelerare le cose: so che contengono una piccola intestazione, quindi molti dati di misurazione, e so che contengono timestamp in tempo reale, quindi Sono abbastanza sicuro che la possibilità che, diciamo, i primi 16 MB di due file siano identici, è molto bassa (perché ciò accada, è necessario creare due file esattamente nello stesso momento, esattamente nelle stesse condizioni ambientali) . Quindi la mia conclusione è che dovrebbe essere sufficiente per hash solo la prima X MB di ogni file.

Funziona sui miei dati di esempio, ma poiché non ho esperienza volevo solo chiedere se c'è qualcosa di cui non sono a conoscenza (pericolo nascosto o un modo migliore per farlo).

Grazie mille!

+2

http://codereview.stackexchange.com/ – vaultah

+1

È necessario fare i calcoli e vedere quanto è probabile che si verifichi una collisione involontaria, oppure è necessario in qualche modo garantire che i diversi file * abbiano sempre * un'intestazione diversa . In quest'ultimo caso, è possibile * di sicuro * checksum solo l'intestazione. Nel primo caso, è necessario decidere autonomamente se la probabilità di collisione è qualcosa con cui si può vivere o meno. È difficile aiutare senza conoscere i tuoi dati. –

+1

Puoi evitare di reinventare la ruota e usare [rsync] (http://en.wikipedia.org/wiki/Rsync). –

risposta

3

è possibile ottenere l'hash MD5 dei file di grandi dimensioni, per breaking them into small byte chunks.

Inoltre, il calcolo degli hash MD5 è significativamente faster than SHA-256 e dovrebbe essere favorito per motivi di prestazioni per qualsiasi applicazione che non si basa sull'hash per motivi di sicurezza.

+0

Ho preso tutti i commenti e le risposte, i link forniti e ora sto usando md5, hash il primo 16 MB, e se ho posto due file con lo stesso hash, ho ricalcolare il loro hash per 32 MB, poi per 64 MB, poi .. ., fino a quando gli hash iniziano a differire, un file riporta EoF ma l'altro no (considerando quei due casi "non uguali") o entrambi i file segnalano EoF e l'hash è lo stesso (considerando i file uguali). Grazie a tutti! – Blutkoete

Problemi correlati