2014-06-24 9 views
5

Ich brauche eine intelligente Kopierfunktion für zuverlässiges und schnelles Kopieren von Dateien & Verknüpfung. Die Dateien sind sehr groß (von einigen Gigabyte bis über 200GB) und verteilt über viele Ordner mit Umbenennungsdateien und vielleicht Ordnern während des Tages, also möchte ich Hashes verwenden, um zu sehen, ob ich bereits eine Datei kopiert habe, vielleicht unter einen anderen Namen, und erstellen Sie nur einen Link in diesem Fall.Ist diese "schnelle Hash" -Funktion gefährlich?

Im neu vollständig zu Hashing und ich bin mit dieser Funktion hier 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() 

Dies dauert eine Minute für eine 3 GB-Datei, so dass am Ende, könnte der Prozess für eine 16TB sehr langsam sein HD.

Jetzt ist meine Idee, etwas zusätzliches Wissen über die interne Struktur der Dateien zu verwenden, um Dinge zu beschleunigen: Ich weiß, dass sie einen kleinen Header, dann eine Menge Messdaten enthalten, und ich weiß, dass sie Echtzeit-Zeitstempel enthalten Ich bin mir ziemlich sicher, dass die Wahrscheinlichkeit, dass die ersten 16MB von zwei Dateien identisch sind, sehr gering ist (dazu müssten zwei Dateien genau zur selben Zeit unter genau denselben Umgebungsbedingungen erstellt werden). . Meine Schlussfolgerung ist, dass es ausreichen sollte, nur die ersten X MB jeder Datei zu hashen.

Es funktioniert auf meinen Beispieldaten, aber da ich unerfahren bin, wollte ich nur fragen, ob es etwas gibt, das mir nicht bekannt ist (versteckte Gefahr oder eine bessere Art, es zu tun).

Vielen Dank!

+2

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

+1

Sie müssen entweder rechnen und sehen, wie wahrscheinlich es ist, dass Sie eine unbeabsichtigte Kollision haben, oder Sie müssen irgendwie garantieren, dass verschiedene Dateien * immer * eine andere Kopfzeile haben . Im letzteren Fall können Sie * sicher * nur die Kopfzeile überprüfen. Im ersten Fall müssen Sie selbst entscheiden, ob die Wahrscheinlichkeit einer Kollision etwas ist, mit dem Sie leben können oder nicht. Es ist schwierig zu helfen, ohne Ihre Daten zu kennen. –

+1

Sie könnten das Rad nicht neu erfinden und [rsync] (http://en.wikipedia.org/wiki/Rsync) verwenden. –

Antwort

3

Sie können den MD5-Hash großer Dateien erhalten, indem Sie breaking them into small byte chunks.

Auch die Berechnung von MD5-Hashes ist signifikant faster than SHA-256 und sollte aus Leistungsgründen für jede Anwendung bevorzugt werden, die aus Sicherheitsgründen nicht auf den Hash-Wert angewiesen ist.

+0

Ich nahm alle Kommentare und Antworten, die bereitgestellten Links und jetzt benutze ich md5, hash die ersten 16MB, und wenn ich zwei Dateien mit dem gleichen Hash, ich neu berechnen ihren Hash für 32MB, dann für 64MB, dann .. ., bis entweder die Hashes zu unterscheiden, eine Datei meldet EoF aber die andere nicht (unter Berücksichtigung dieser beiden Fälle "nicht gleich") oder beide Dateien melden EoF und der Hash ist der gleiche (unter Berücksichtigung der Dateien gleich). Danke euch allen! – Blutkoete