Warum diese beiden Dateien Hash auf den gleichen Wert, wenn ich Memory?
-
19-09-2019 - |
Frage
Ich schreibe eine c # Routine, die Hashes von jpg-Dateien erstellt. Wenn ich in einem Byte-Array zu meinem SHA512-Objekt übergebe dann bekomme ich das Verhalten jedoch zu erwarten, wenn ich in einem Speicher passiere auf den gleichen Wert die beiden Dateien immer Hash streamen.
Beispiel 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");
erzeugt, das "Different Hashes". Aber eine der Überlastung der ComputeHash Methode nimmt ein Stream-Objekt in und ich mag lieber, dass verwenden. Wenn ich tun:
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");
Das erzeugt "Gehashte die gleiche".
Was ist denn hier los, dass ich fehle?
Lösung
Sie Ihre MemoryStreams nicht zurückgespult, so dass der Hash aus einer leeren Folge von Bytes berechnet wird. Mit
ms1.Position = 0;
ms2.Position = 0;
nach dem Aufruf Save
.
Noch ein Hinweis: nicht GetBuffer
auf diese Weise verwenden. Verwenden ToArray
, die Ihnen eine Byte-Array die gleiche Größe wie die Länge des Stromes geben werden - GetBuffer
kehrt den rohen Puffer, der (in der Regel) etwas Padding hat, die Sie nicht versehentlich verwenden mögen. Sie können GetBuffer
verwenden, wenn Sie dann sicher, dass Sie nur den relevanten Teil davon verwenden, natürlich -. Dies vermeidet eine neue Kopie der Daten zu erstellen