¿Por qué estos dos archivos hash al mismo valor cuando uso MemoryStream?
-
19-09-2019 - |
Pregunta
Estoy escribiendo una rutina c # que crea valores hash de los archivos jpg. Si paso en una matriz de bytes a mi objeto SHA512 entonces consigo el comportamiento esperado, sin embargo, si paso en una memoria transmitir los dos archivos siempre hash al mismo valor.
Ejemplo 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");
Eso produce "Diferentes valores hash". Pero una de las sobrecargas del método ComputeHash toma un objeto de secuencia y prefiero usar eso. Cuando hago:
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");
que produce "HASHED la misma".
Lo que está pasando aquí que me falta?
Solución
Usted no está rebobinando sus MemoryStreams, por lo que el hash se calcula a partir de una secuencia vacía de bytes. Uso
ms1.Position = 0;
ms2.Position = 0;
después de llamar Save
.
Una nueva nota: no utilice GetBuffer
de esta manera. Utilice ToArray
que le dará una matriz de bytes del mismo tamaño que la longitud de la corriente - GetBuffer
devuelve el búfer prima que (por lo general) tienen algo de relleno, que no se desea utilizar de forma accidental. Puede utilizar GetBuffer
si a continuación, asegúrese de que sólo utiliza la parte relevante de la misma, por supuesto -. Esto evita la creación de una nueva copia de los datos