2011-10-15 9 views
5

Tengo un requisito para 'verificar la integridad' del contenido de los archivos. Los archivos se escribirán en CD/DVD, que se pueden copiar muchas veces. La idea es identificar las copias (después de que se eliminen de Nero, etc.) que se copiaron correctamente.Confirmación del contenido del archivo contra el hash

Soy bastante nuevo en esto, pero una búsqueda rápida sugiere que Arrays.hashCode(byte[]) se ajustará a la necesidad. Podemos incluir un archivo en el disco que contiene el resultado de esa llamada para cada recurso de interés, luego compararlo con el byte[] del File como leído desde el disco cuando se marca.

¿Entiendo el método correctamente? ¿Es esta una forma válida de verificar el contenido del archivo?

De lo contrario, se agradecerían las sugerencias sobre palabras clave de búsqueda o estrategias/métodos/clases.


Código de trabajo basado en la respuesta de Brendan. Se encarga del problema identificado por VoidStar (necesita tener todo el byte[] en memoria para obtener el 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); 
    } 
} 

Respuesta

8

Arrays.hashCode() está diseñado para ser muy rápido (utilizado en las tablas hash). Recomiendo encarecidamente no usarlo para este propósito.

Lo que quiere es algún tipo de código de comprobación de errores como CRC.

Java pasa a tener una clase para el cálculo de éstas: 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

Muchas gracias. Ahora tengo código de trabajo (editado en cuestión) con el que estoy contento. –

1

Sí, siempre que cargue todo el archivo y lo transfiera, funcionará como se esperaba. Sin embargo, consumirá tanta RAM como el archivo sea grande, lo que no es necesario para esta tarea. Si, en cambio, hash el archivo en bloques más pequeños a medida que lo transmites desde el almacenamiento, puedes evitar desperdiciar memoria. Podría, por ejemplo, combinar los valores hash de cada bloque para crear un hash final o encontrar una implementación hash que espere que se transmitan los datos.

+0

Gracias por sus comentarios. No había pensado en las dificultades de cargar todo el archivo en la memoria. Eso se puede resolver usando el CRC32 como lo sugiere Brendan. –

Cuestiones relacionadas