2011-10-15 24 views
5

Ho il requisito di "verificare l'integrità" del contenuto di file. I file verranno scritti su CD/DVD, che potrebbe essere copiato molte volte. L'idea è di identificare le copie (dopo che sono state rimosse da Nero ecc.) Che sono state copiate correttamente.Confermare il contenuto del file con l'hash

Sono piuttosto nuovo a questo, ma una ricerca rapida suggerisce che il numero Arrays.hashCode(byte[]) soddisferà l'esigenza. Possiamo includere un file sul disco che contiene il risultato di quella chiamata per ogni risorsa di interesse, quindi confrontarlo con lo byte[] dello File come letto dal disco quando selezionato.

Ho capito correttamente il metodo, è un modo valido per controllare il contenuto del file?

In caso contrario, sarebbero graditi suggerimenti per la ricerca di parole chiave o strategie/metodi/classi.


Codice di lavoro basato sulla risposta di Brendan. Si occupa del problema identificato da VoidStar (è necessario tenere in memoria l'intero per ottenere l'hash).

import java.io.File; 
import java.io.FileInputStream; 
import java.util.zip.CRC32; 

class TestHash { 

    public static void main(String[] args) throws Exception { 
     File f = new File("TestHash.java"); 
     FileInputStream fis = new FileInputStream(f); 
     CRC32 crcMaker = new CRC32(); 
     byte[] buffer = new byte[65536]; 
     int bytesRead; 
     while((bytesRead = fis.read(buffer)) != -1) { 
      crcMaker.update(buffer, 0, bytesRead); 
     } 
     long crc = crcMaker.getValue(); // This is your error checking code 
     System.out.println("CRC code is " + crc); 
    } 
} 

risposta

8

Arrays.hashCode() è stato progettato per essere molto veloce (utilizzato in tabelle hash). Consiglio vivamente di non utilizzarlo per questo scopo.

Quello che vuoi è una sorta di codice di controllo degli errori come un CRC.

Java succede ad avere una classe per calcolare questi: CRC32:

InputStream in = ...; 
CRC32 crcMaker = new CRC32(); 
byte[] buffer = new byte[someSize]; 
int bytesRead; 
while((bytesRead = in.read(buffer)) != -1) { 
    crcMaker.update(buffer, 0, bytesRead); 
} 
long crc = crcMaker.getValue(); // This is your error checking code 
+0

Grazie mille. Ora ho un codice funzionante (modificato in questione) di cui sono felice. –

1

Sì, finché si carica l'intero file e lo si inoltra, esso funzionerà come previsto. Tuttavia, consumerà la quantità di RAM del file è grande, che non è necessario per questa attività. Se invece si esegue l'hash del file in blocchi più piccoli mentre lo si esegue in streaming dallo storage, è possibile evitare di sprecare memoria. È possibile, ad esempio, xorare insieme gli hash di ciascun blocco per creare un hash finale o trovare un'implementazione hash che si aspetta che i dati vengano trasmessi in streaming.

+0

Grazie per i vostri commenti. Non avevo pensato alle difficoltà di caricare l'intero file in memoria. Questo può essere risolto utilizzando il CRC32 come suggerito da Brendan. –

Problemi correlati