Estou desenvolvendo um sistema que faz download de pequenos arquivos de um Servidor FTP. Após o download, esse sistema apaga os arquivos do servidor.
Eu gostaria de verificar a integridade dos arquivos, antes de apagá-los.
Pensei em checar o tamanho do arquivo baixado e comparar com o arquivo existente no servidor, mas penso que isso não consiga pegar arquivos que por algum motivo forem alterados durante o download.
Então pensei em fazer um checksum. Já pesquisei algumas coisas no google.
Vale a pena mesmo usar um checksum? Isso afetará demais o desempenho do sistema?
Pra quem já utilizou isso, usou alguma biblioteca específica? Alguma sugestão?
Edit: Estou usando a lib da apache para fazer as transações ftp. Será que ela já tem algo referente a isso que ainda não encontrei?
A JRE já vem inclusive com uma implementação do mesmo.
Com relação à performance, o que posso dizer é o seguinte: varia de acordo com o tamanho dos arquivos.
Se forem grandes, com certeza você sentirá o impacto.
Mas nesta questão, o que cabe é você pensar o que pesa mais: a garantia de integridade dos seus dados ou a performance desejada?
A JRE já vem inclusive com uma implementação do mesmo.
Com relação à performance, o que posso dizer é o seguinte: varia de acordo com o tamanho dos arquivos.
Se forem grandes, com certeza você sentirá o impacto.
Mas nesta questão, o que cabe é você pensar o que pesa mais: a garantia de integridade dos seus dados ou a performance desejada?[/quote]
Olhando a API do java SE, encontrei a interface CheckSum.
tenho, mas usando em uma String, neste link no meu blog: http://www.itexto.net/devkico/?p=5
O código está em Groovy mas é quase idêntico ao que você criaria em Java.
E, a outra adaptação que você tem de fazer é no MessageDigest, que ao invés de receber uma string, vai ter de receber um array de bytes.
A interface CheckSum é implementada pelas classes Adler e CRC32 mas eu usaria um MD5 - é mais seguro que um simples CRC32. Rode o programa abaixo e veja porque é que não se recomenda usar Adler32.
[quote=thingol]A interface CheckSum é implementada pelas classes Adler e CRC32 mas eu usaria um MD5 - é mais seguro que um simples CRC32. Rode o programa abaixo e veja porque é que não se recomenda usar Adler32.
Esse método hex serve pra pegar a representação hexadecimal de cada byte no array passado? Ou entendi errado?
Como que usa tudo isso pra ver que um arquivo baixado é uma cópia identica de um arquivo num servidor?
class TesteMD5 {
private static char[] hexDigits = "0123456789ABCDEF".toCharArray();
private static String hex (byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append (hexDigits[(b & 0xF0) >>> 4]).append (hexDigits[b & 0x0F]);
}
return sb.toString();
}
public static String calcMD5 (File f) {
try {
MessageDigest md = MessageDigest.getInstance ("MD5");
InputStream is = null;
try {
is = new BufferedInputStream (new FileInputStream (f));
byte[] buf = new byte[8192];
for (int nBytes = is.read (buf, 0, buf.length); nBytes > 0; nBytes = is.read (buf, 0,
buf.length)) {
md.update (buf, 0, nBytes);
}
} catch (IOException ex) {
if (is != null) try { is.close(); } catch (IOException ex2) { }
}
byte[] digest = md.digest();
return hex (digest);
} catch (NoSuchAlgorithmException ex) {
// MD5 sempre está disponível
throw new RuntimeException (“Can’t happen”, ex);
}
}
public static void main (String[] args) {
System.out.println (calcMD5 (new File (“teste.bin”)));
}
}
[/code][/quote]
Obrigado Thingol.
Pelo que entendi, o que preciso fazer é o seguinte:
1- Calcular o md5 do arquivo que está no servidor FTP, antes de baixá-lo.
2- Baixar o arquivo.
3- Calcular o md5 do arquivo depois de baixado.
4- Comparar os dois md5’s gerados e considerar que o arquivo foi corretamente baixado somente se ambos forem exatamente iguais.
Nenhum - até porque o MD5 foi “quebrado” recentemente, e não deve ser usado para fins sérios (como assinatura digital).
A Microsoft, por exemplo, prefere que você use o SHA-1 para verificar os downloads dos arquivos do site deles.
É só uma questão de costume (por exemplo, muitos sites oferecem downloads e com o hash MD5 também); se quiser, pode usar o SHA-512 (por exemplo).
É que o MD5, desses hashes que já vêm com o JDK, é o mais rápido (se não me engano, não fiz nenhum teste de desempenho), e não gera um hash muito grande. O MD5 são 16 bytes, mas o SHA-512 são 64 bytes.