MD5
è detto abbastanza lento (vedi sotto). Il digest MD5
è piuttosto lungo. Suggerirei il tempo di modifica, la dimensione e il% di checksum diCRC-32
per i confronti tra file. Una discussione su CRC-32
è qui . Come suggerisce il nome, CRC-32
ha valori hash a 32 bit. Un'implementazione Java è disponibile in java.util.zip.CRC32
Modifica
Il vantaggio di velocità di CRC-32 rispetto a MD5 è inferiore a quello che mi aspettavo. CRC-32 ha bisogno di circa il 20% di tempo in meno rispetto a MD5.
Ho usato il seguente codice Java per trovare la differenza (e demo l'uso di entrambi i metodi):
import java.security.*;
import java.util.Random;
import java.util.zip.CRC32;
public class HashBench {
@SuppressWarnings("unused")
public static void main(String[] args) throws Exception {
int noOfLoopIterations = 100 * 1000;
int bytesInMessageBuffer = 100 * 1024;
byte randomByteBuffer[] = new byte[bytesInMessageBuffer];
byte md5Digest[];
MessageDigest md5;
CRC32 crc;
long crcValue;
long startTime;
long elapsedTime;
new Random().nextBytes(randomByteBuffer);
// MD5 benchmark
o("Starting MD5 benchmark ...(" + bytesInMessageBuffer/1024 + "KByte messages)");
md5 = MessageDigest.getInstance("MD5");
startTime = System.nanoTime();
for (int i = 1; i < noOfLoopIterations; i++)
{
md5Digest = md5.digest(randomByteBuffer);
}
showElapsed(noOfLoopIterations, startTime);
// CRC-32 benchmark
o("Starting CRC-32 benchmark ... (" + bytesInMessageBuffer/1024 + "KByte messages)");
crc = new CRC32();
startTime = System.nanoTime();
for (int i = 1; i < noOfLoopIterations; i++)
{
crc.reset();
crc.update(randomByteBuffer);
crcValue = crc.getValue();
}
showElapsed(noOfLoopIterations, startTime);
o("Ciao!");
}
private static void showElapsed(int noOfLoopIterations, long startTime) {
long elapsedTime;
elapsedTime = System.nanoTime() - startTime;
o("Elapsed time: " + num(elapsedTime / 1000000000.0) + "s for " + String.format("%1$,.0f", 1.0 * noOfLoopIterations) + " loops");
o("Time per digest: " + num(elapsedTime / (1000000.0 * noOfLoopIterations)) + "ms");
o("");
}
private static void o(String s) {
System.out.println(s);
}
private static String num(double x) {
return String.format("%1$,.2f", x);
}
}
Il risultato:
Starting MD5 benchmark ...(100KByte messages)
Elapsed time: 28,94s for 100.000 loops
Time per digest: 0,29ms
Starting CRC-32 benchmark ... (100KByte messages)
Elapsed time: 23,89s for 100.000 loops
Time per digest: 0,24ms
Per evitare l'influenza del caching del disco e altri effetti esterni, riempio semplicemente un array di byte con valori casuali. Il benchmark esegue ripetutamente il calcolo dell'hash / checksum.
Conclusione: la velocità di calcolo non è un motivo convincente in questo caso.