Pergunta

Estou escrevendo rotina AC# que cria hashes a partir de arquivos jpg. Se eu passar em uma matriz de bytes para o meu objeto SHA512, eu recebo o comportamento esperado, no entanto, se eu passar em um fluxo de memória, os dois arquivos sempre hash para o mesmo valor.

Exemplo 1:

        SHA512 mySHA512 = SHA512.Create();

        Image img1 = Image.FromFile(@"d:\img1.jpg");
        Image img2 = Image.FromFile(@"d:\img2.jpg");
        MemoryStream ms1 = new MemoryStream();
        MemoryStream ms2 = new MemoryStream();

        img1.Save(ms1, ImageFormat.Jpeg);
        byte[] buf1 = ms1.GetBuffer();
        byte[] hash1 = mySHA512.ComputeHash(buf1);

        img2.Save(ms2, ImageFormat.Jpeg);
        byte[] buf2 = ms2.GetBuffer();
        byte[] hash2 = mySHA512.ComputeHash(buf2);

        if (Convert.ToBase64String(hash1) == Convert.ToBase64String(hash2))
            MessageBox.Show("Hashed the same");
        else
            MessageBox.Show("Different hashes");

Que produz "hashes diferentes". Mas uma das sobrecargas do método de computação leva um objeto de fluxo e eu prefiro usar isso. Quando eu faço:

        SHA512 mySHA512 = SHA512.Create();

        Image img1 = Image.FromFile(@"d:\img1.jpg");
        Image img2 = Image.FromFile(@"d:\img2.jpg");
        MemoryStream ms1 = new MemoryStream();
        MemoryStream ms2 = new MemoryStream();

        img1.Save(ms1, ImageFormat.Jpeg);
        byte[] hash1 = mySHA512.ComputeHash(ms1);

        img2.Save(ms2, ImageFormat.Jpeg);
        byte[] hash2 = mySHA512.ComputeHash(ms2);

        if (Convert.ToBase64String(hash1) == Convert.ToBase64String(hash2))
            MessageBox.Show("Hashed the same");
        else
            MessageBox.Show("Different hashes");

Que produz "hash o mesmo".

O que está acontecendo aqui que estou perdendo?

Foi útil?

Solução

Você não está retrocedendo suas formas de memória, então o hash é calculado a partir de uma sequência vazia de bytes. Usar

ms1.Position = 0;
ms2.Position = 0;

Depois de ligar Save.

Uma nota adicional: não use GetBuffer nesse caminho. Usar ToArray que lhe dará uma matriz de byte do mesmo tamanho que o comprimento do fluxo - GetBuffer Retorna o buffer bruto que (geralmente) terá algum preenchimento, que você não gostaria de usar acidentalmente. Você pode usar GetBuffer Se você certifique -se de usar apenas a parte relevante, é claro - isso evita a criação de uma nova cópia dos dados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top