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?
R
rodrigo.bossini
kicolobo:
Você pode usar o MD5 mesmo.
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?
Olhando a API do java SE, encontrei a interface CheckSum.
Você tem um exemplo de como utilizar?
K
kicolobo
Tenho um para MD5.
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.
T
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.
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?
T
thingol
Tá bom, tá bom, vamos escrever um método que lê um arquivo e calcula seu MD5.
importjava.util.*;importjava.io.*;importjava.security.*;classTesteMD5{privatestaticchar[]hexDigits="0123456789ABCDEF".toCharArray();privatestaticStringhex(byte[]bytes){StringBuildersb=newStringBuilder();for(byteb:bytes){sb.append(hexDigits[(b&0xF0)>>>4]).append(hexDigits[b&0x0F]);}returnsb.toString();}publicstaticStringcalcMD5(Filef){try{MessageDigestmd=MessageDigest.getInstance("MD5");InputStreamis=null;try{is=newBufferedInputStream(newFileInputStream(f));byte[]buf=newbyte[8192];for(intnBytes=is.read(buf,0,buf.length);nBytes>0;nBytes=is.read(buf,0,buf.length)){md.update(buf,0,nBytes);}}catch(IOExceptionex){if(is!=null)try{is.close();}catch(IOExceptionex2){}}byte[]digest=md.digest();returnhex(digest);}catch(NoSuchAlgorithmExceptionex){// MD5 sempre está disponívelthrownewRuntimeException("Can't happen",ex);}}publicstaticvoidmain(String[]args){System.out.println(calcMD5(newFile("teste.bin")));}}
R
rodrigo.bossini
thingol:
Tá bom, tá bom, vamos escrever um método que lê um arquivo e calcula seu MD5.
importjava.util.*;importjava.io.*;importjava.security.*;classTesteMD5{privatestaticchar[]hexDigits="0123456789ABCDEF".toCharArray();privatestaticStringhex(byte[]bytes){StringBuildersb=newStringBuilder();for(byteb:bytes){sb.append(hexDigits[(b&0xF0)>>>4]).append(hexDigits[b&0x0F]);}returnsb.toString();}publicstaticStringcalcMD5(Filef){try{MessageDigestmd=MessageDigest.getInstance("MD5");InputStreamis=null;try{is=newBufferedInputStream(newFileInputStream(f));byte[]buf=newbyte[8192];for(intnBytes=is.read(buf,0,buf.length);nBytes>0;nBytes=is.read(buf,0,buf.length)){md.update(buf,0,nBytes);}}catch(IOExceptionex){if(is!=null)try{is.close();}catch(IOExceptionex2){}}byte[]digest=md.digest();returnhex(digest);}catch(NoSuchAlgorithmExceptionex){// MD5 sempre está disponívelthrownewRuntimeException("Can'thappen",ex);}}publicstaticvoidmain(String[]args){System.out.println(calcMD5(newFile("teste.bin")));}}
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.
É isso mesmo?
R
Rubem_Azenha
Thingol, algum motivo particular pra escolher MD5 em vez de SHA1?
T
thingol
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.