2009-11-11 3 views
5

J'écris une routine C# qui crée des hachages à partir de fichiers jpg. Si je passe dans un tableau d'octets à mon objet SHA512 alors j'obtiens le comportement attendu, cependant, si je passe dans un flux de mémoire, les deux fichiers ont toujours la même valeur.Pourquoi ces deux fichiers ont-ils la même valeur lorsque j'utilise MemoryStream?

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

qui produit "différentes hash". Mais l'une des surcharges de la méthode ComputeHash prend un objet stream 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"); 

Cela produit "Hashed le même".

Que se passe-t-il ici?

+0

Ce ne sont pas des copies de l'image _same_, n'est-ce pas? –

+0

Que se passe-t-il si vous recherchez le début du flux après l'appel .Save? par exemple. ms1.Seek (0, SeekOrigin.Begin); – Joe

+0

Dans ce cas, vous pouvez utiliser 'mySHA512.ComputeHash.ComputeHash (ms1.GetBuffer(), 0, (int) ms1.Length)'. Évite les copies inutiles – CodesInChaos

Répondre

14

Vous ne rembobinez pas vos MemoryStreams. Le hachage est donc calculé à partir d'une séquence vide d'octets. Utilisez

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

après avoir appelé Save.

Une autre note: n'utilisez pas GetBuffer de cette manière. Utilisez ToArray qui vous donnera un tableau d'octets de la même taille que la longueur du flux - GetBuffer renvoie le tampon brut qui aura (généralement) un peu de rembourrage, que vous ne voudriez pas utiliser accidentellement. Vous pouvez utiliser GetBuffer si vous vous assurez alors que vous n'utilisez que la partie pertinente de celui-ci, bien sûr - cela évite de créer une nouvelle copie des données.

+0

Merci pour le conseil, ça marche! –

Questions connexes