Domanda

Sto scrivendo un c # routine che crea hash da file jpg. Se mi passa in un array di byte per il mio oggetto SHA512 allora ottengo il comportamento previsto, tuttavia, se mi passa in una memoria flusso i due file hash sempre per lo stesso valore.

Esempio 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");

Ciò produce "Different hash". Ma uno degli overload del metodo ComputeHash prende un oggetto stream e io preferisco usare quello. Quando faccio:

        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");

che produce "hash lo stesso".

Che cosa sta succedendo qui che mi manca?

È stato utile?

Soluzione

Non stai riavvolgimento tuoi MemoryStreams, così l'hash viene calcolato da una sequenza vuota di byte. Usa

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

dopo aver chiamato Save.

Un altro nota: non utilizzare GetBuffer in questo modo. Utilizzare ToArray che vi darà un array di byte la stessa dimensione come la lunghezza del flusso - GetBuffer restituisce il buffer di grezzo che (di solito) avere qualche chilo, che non si vuole usare accidentalmente. È possibile utilizzare GetBuffer se quindi assicurarsi di utilizzare solo la parte rilevante di esso, ovviamente -. Questo evita la creazione di una nuova copia dei dati

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top