Pourquoi ces deux fichiers de hachage à la même valeur quand je l'utilise MemoryStream?
-
19-09-2019 - |
Question
J'écris une routine c # qui crée hash des fichiers jpg. Si je passe dans un tableau d'octets à mon objet SHA512 puis-je obtenir le comportement attendu, cependant, si je passe dans une mémoire flux les deux fichiers de hachage toujours à la même valeur.
Exemple 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");
Ce produit "Different hash". Mais l'une des surcharges de la méthode ComputeHash prend un objet courant et je préfère l'utiliser. Quand je fais:
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");
Ce produit "HASHED même".
Qu'est-ce qui se passe ici que je suis absent?
La solution
Vous n'êtes pas rembobiner vos MemoryStreams, de sorte que le hachage est calculée à partir d'une séquence d'octets vide. Utilisez
ms1.Position = 0;
ms2.Position = 0;
après avoir appelé Save
.
Une autre note: ne pas utiliser GetBuffer
de cette façon. Utilisez ToArray
qui vous donnera un tableau d'octets la même taille que la longueur du flux - GetBuffer
retourne le tampon brut qui (habituellement) avoir un rembourrage, que vous ne voulez pas utiliser accidentellement. Vous pouvez utiliser GetBuffer
si vous alors assurez-vous d'utiliser uniquement la partie pertinente de celui-ci, bien sûr -. Ce qui évite la création d'une nouvelle copie des données