Comparação de Pdf

Pessoal,

estou precisando realizar uma comparação entre arquivos pdf em meu sistema, pois o usuário não pode anexar o mesmo arquivo 2 vezes.
Uma comparação muito ruim seria pelo nome do arquivo, mas vai que o usuário renomeia o arquivo e acaba anexando ele denovo, ai essa comparação por novo já não iria funcionar, barraria somente alguns arquivos.

Você não quer que o mesmo arquivo (binariamente falando) seja anexado 2 vezes? (Ou seja, você pode anexar uma versão mais nova, ligeiramente modificada do PDF)?

Se for assim, é relativamente simples. Calculer o MD5 ou o SHA-1 do arquivo e guarde esse valor. Se porventura o usuário quiser anexar EXATAMENTE O MESMO arquivo (mesmo que com nome diferente), o MD5 ou SHA-1 vai bater, e então nesse caso você não deixa. Se mudar um byte que seja, o MD5 ou SHA-1 não vai bater.

Exatamente, não quero que o mesmo arquivo seja anexado 2 vezes.
Não entendi direito isso:

Acho que se o arquivo está levemente modificado, o usuário não precisaria anexar este outro documento.

De qualquer forma, como que eu faria pra calcular esse MD% ou SHA-1 dos arquivos?

É que é muito mais difícil você saber se um arquivo foi ligeiramente modificado, e se essa alteração é significativa ou não (por exemplo, um texto tinha “R$99,99” e agora tem “R$99,98” - uma alteração de tabela de preços, por exemplo), que simplesmente fazer uma comparação binária.
Fazer uma comparação binária é muito simples.

Entendi,

bom acho que se o ducumento foi levemente modificado não iria ter problema, então ele poderia anexar este documento.
Neste caso teria que calcular o MD5 ou SHA-1 de cada arquivo pra ver se eles batem.
Como faço esta verificação? Existe algum exemplo aqui no forum pra eu pegar como base?

Bom…
Aqui vai um exemplo (para eu não anexar um arquivo de teste aqui, eu simplesmente crio o arquivo só para você poder ver como é que funciona).

import java.io.*;
import java.util.*;
import java.security.*;

class CalcularHashArquivo {

    private static String hex (byte[] bytes) {
        StringBuilder sb = new StringBuilder (bytes.length * 2);
        Formatter fmt = new Formatter (sb);
        for (int i = 0; i < bytes.length; ++i) {
            fmt.format ("%02X", bytes[i] & 0xFF);
        }
        return sb.toString();
    }

    // Este método faz o cálculo do MD5, SHA1 etc. de um arquivo qualquer. 
    public static String calcular (File nomeArquivo, MessageDigest md) throws IOException {
        md.reset();
        DigestInputStream dis = new DigestInputStream (new BufferedInputStream (new FileInputStream (nomeArquivo)), md);
        byte[] bytes = new byte[8 * 1024];
        while (dis.read(bytes) > 0) {
            ;
        }
        dis.close();
        byte[] digest = md.digest();
        return hex (digest);
    }
    
    // Teste
    public static void main (String[] args) throws Exception {
        // Aqui vamos usar o MD5, mas podemos usar um outro hash, como o SHA-1. Basta mudar o argumento
        MessageDigest md = MessageDigest.getInstance ("MD5");
        // Criando um arquivo de teste de 1MB - tamanho típico para um PDF
        // Só para ficar mais interessante, vou criar com dados aleatórios
        // (em vez de deixar cheio de zeros).
        Random r = new Random (1234L); // pus 1234L para forçar a gerar dados "aleatórios" mas conhecidos
        File f = new File ("teste.bin");
        FileOutputStream fos = new FileOutputStream (f);
        byte[] bytes = new byte[1024 * 1024];
        r.nextBytes (bytes); // isto preenche com 1 MB de dados aleatórios
        fos.write (bytes);
        fos.close();
        // Calculando o MD5 e o imprimindo
        String md5_arquivo1 = CalcularHashArquivo.calcular (f, md);
        System.out.println (md5_arquivo1); // imprime 00EBBF29153FEF4EB5E4A9E48C8AA87F
        // Agora criando um arquivo igualzinho
        f = new File ("teste2.bin");
        fos = new FileOutputStream (f);
        fos.write (bytes);
        fos.close();
        String md5_arquivo2 = CalcularHashArquivo.calcular (f, md);
        System.out.println (md5_arquivo2); // imprime 00EBBF29153FEF4EB5E4A9E48C8AA87F
        // Agora criando um arquivo que tem apenas 1 bit de diferença, na posição 500000
        // Veja que o valor vai dar completamente diferente. 
        f = new File ("teste3.bin");
        bytes[500000] ^= 0x01; // isso mexe em apenas 1 bit
        fos = new FileOutputStream (f);
        fos.write (bytes);
        fos.close();
        String md5_arquivo3 = CalcularHashArquivo.calcular (f, md);
        System.out.println (md5_arquivo3); // imprime B46B2696D997EA2C436FAEBB129354B0
    }
}

ok,

valeu pela ajuda.

Vou testar aqui assim que tiver um tempinho.

flw