Um zu überprüfen, ob zwei Bilddateien gleich sind..Checksum oder Hash?

8

Ich mache etwas Bildverarbeitungscode, wo ich einige Bilder (als BufferedImage) von URLs herunterlade und sie an einen Bildprozessor weitergebe.

Ich möchte vermeiden, dass dasselbe Bild mehr als einmal an den Bildprozessor weitergegeben wird (da der Bildverarbeitungsvorgang hohe Kosten verursacht). Die URL-Endpunkte der Bilder (wenn es sich um dieselben Bilder handelt) können variieren und daher kann ich dies durch die URL verhindern. Daher plante ich, eine Prüfsumme oder einen Hashwert zu verwenden, um festzustellen, ob der Code erneut auf dasselbe Bild trifft.

Für md5 habe ich Fast MD5 ausprobiert und einen Hex-Prüfsummenwert von 20K + Zeichenlänge für das Bild generiert ( etwas Probe). Offensichtlich ist das Speichern dieses 20K + -Zeichen-Hashes ein Problem, wenn es um den Datenbankspeicher geht. Daher habe ich das CRC32 (von java.util.zip.CRC32) versucht. Und es hat eine etwas kleinere Prüfsumme erzeugt als der Hash.

Ich verstehe, Prüfsumme und Hash sind für verschiedene Zwecke. Für den oben erläuterten Zweck kann ich einfach den CRC32 verwenden? Würde es den Zweck lösen oder ich müsste etwas mehr als diese beiden versuchen?

Danke, Abi

    
Abhishek 17.06.2011, 06:27
quelle

3 Antworten

5

Der Unterschied zwischen CRC und, sagen wir, MD5 besteht darin, dass es schwieriger ist, eine Datei so zu manipulieren, dass sie einem "Ziel" -MD5 entspricht, als sie zu manipulieren, um sie einer "Ziel" -Checksumme anzupassen. Da dies für Ihr Programm kein Problem darstellt, sollte es keine Rolle spielen, welche Methode Sie verwenden. Vielleicht ist MD5 ein bisschen mehr CPU-intensiv, aber ich weiß nicht, ob das anders ist.

Die Hauptfrage sollte die Anzahl der Bytes des Digests sein.

Wenn Sie eine Prüfsumme in einer Ganzzahl eingeben, bedeutet dies, dass Sie für eine Datei mit 2K Größe 2 ^ 2048 Kombinationen in 2 ^ 32 Kombinationen einfügen - & gt; Für jeden CRC-Wert haben Sie 2 ^ 64 mögliche Dateien, die dem entsprechen. Wenn Sie ein 128-Bit-MD5 haben, dann haben Sie 2 ^ 16 mögliche Kollisionen.

Je größer der Code, den Sie berechnen, desto weniger mögliche Kollisionen (da die berechneten Codes gleichmäßig verteilt sind), desto sicherer ist die Vergleichbarkeit.

Wie auch immer, um mögliche Fehler zu minimieren, denke ich, dass die erste Klassifizierung die Dateigröße verwenden sollte ... vergleichen Sie zuerst die Dateigrößen, wenn sie übereinstimmen, dann vergleichen Sie die Prüfsummen / Hash.

    
SJuan76 17.06.2011 06:52
quelle
1

Eine Checksumme und ein Hash sind grundsätzlich gleich. Sie sollten in der Lage sein, jede Art von Hash zu berechnen. Ein regulärer MD5 würde normalerweise ausreichen. Wenn Sie möchten, können Sie die Größe und den md5-Hash speichern (was 16 Bytes ist, denke ich).

Wenn zwei Dateien unterschiedliche Größen haben, sind das verschiedene Dateien. Sie müssen nicht einmal einen Hash über die Daten berechnen. Wenn es unwahrscheinlich ist, dass Sie viele doppelte Dateien haben und die Dateien von der größeren Art sind (wie JPG-Bilder, die mit einer Kamera aufgenommen wurden), kann Ihnen diese Optimierung viel Zeit ersparen.

Wenn zwei oder mehr Dateien dieselbe Größe haben, können Sie die Hashes berechnen und vergleichen.

Wenn zwei Hashwerte identisch sind, könnten Sie die tatsächlichen Daten vergleichen, um zu sehen, ob dies überhaupt anders ist. Das ist sehr, sehr unwahrscheinlich, aber theoretisch möglich. Je größer Ihr Hash ist (md5 ist 16 Byte, während CR32 nur 4 ist), desto weniger wahrscheinlich, dass zwei verschiedene Dateien den gleichen Hash haben. Es dauert nur 10 Minuten, um diese zusätzliche Prüfung durchzuführen, also würde ich sagen: besser als Nachsicht. :)

Um dies weiter zu optimieren, können Sie, wenn genau zwei Dateien dieselbe Größe haben, einfach ihre Daten vergleichen. Sie müssen die Dateien trotzdem lesen, um ihre Hashes zu berechnen. Warum also nicht direkt vergleichen, wenn sie die einzigen beiden mit dieser spezifischen Größe sind.

    
GolezTrol 17.06.2011 06:52
quelle
-3

Zum Vergleichen zweier gepufferter Bilder können Sie BufferedImage.equals () verwenden und zur Vereinfachung können Sie BufferedImage.hashCode () verwenden, um einen Hash des Bildes zu erhalten, das schnell und schnell ist.

    
Asad Rasheed 17.06.2011 07:45
quelle