Perché questi due file hash allo stesso valore quando uso MemoryStream?
-
19-09-2019 - |
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?
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