(РЕДАКТИРОВАТЬ: Утилизация алгоритмов хеширования сейчас. Я подозреваю, что это не нужно, но это хорошая практика:)
Вы вызываете ComputeHash для целого буфера, даже если вы должны хэшировать только часть буфера, которую вы прочитали. Кроме того, вы вычисляете новый хэш для каждого вызова Read.
Вот действительно простой код для вычисления хэшей:
using System;
using System.IO;
using System.Security.Cryptography;
class Test
{
static void Main()
{
byte[] plaintext = File.ReadAllBytes("b.txt");
using (MD5 md5 = MD5.Create())
{
byte[] md5Hash = md5.ComputeHash(plaintext);
Console.WriteLine(BitConverter.ToString(md5Hash));
}
using (SHA1 sha1 = SHA1.Create())
{
byte[] sha1Hash = sha1.ComputeHash(plaintext);
Console.WriteLine(BitConverter.ToString(sha1Hash));
}
}
}
Это дает результаты согласно википедии - обратите внимание, что b.txt
не должно иметь перевод строки в конце.
Альтернативный способ начать с двоичных данных:
byte[] plaintext = Encoding.ASCII.GetBytes(
"The quick brown fox jumps over the lazy dog");
Обратите внимание, что это простой способ вычисления хэша за один раз. Если вы хотите сделать это в потоковом режиме (то есть, когда вы читаете некоторые данные, добавляете их в хеш, читаете еще некоторые данные и т. Д.), То вы можете использовать перегрузку ComputeHash(Stream)
или (если вы хотите «протолкнуть» данные к нему) вы можете использовать TransformBlock
и TransformFinalBlock
, например:
using System.Text;
class Test
{
static void Main()
{
using (MD5 md5 = MD5.Create())
using (SHA1 sha1 = SHA1.Create())
using (Stream input = File.OpenRead("b.txt"))
{
// Artificially small to make sure there's
// more than one read
byte[] buffer = new byte[4];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
md5.TransformBlock(buffer, 0, bytesRead, null, 0);
sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
}
md5.TransformFinalBlock(buffer, 0, 0);
sha1.TransformFinalBlock(buffer, 0, 0);
Console.WriteLine(BitConverter.ToString(md5.Hash));
Console.WriteLine(BitConverter.ToString(sha1.Hash));
}
}
}
Обратите внимание, как мы передаем null
в TransformBlock
, потому что нам не нужен вывод, и мы не преобразуем никаких данных в последний блок. Я подозреваю, что это пример, который вы захотите использовать, основываясь на ваших предыдущих комментариях.