2013-02-15 2 views
4

У меня есть программа, которая будет использоваться на очень больших файлах (текущие тестовые данные - 250 ГБ). Мне нужно уметь вычислять хэши MD5 и SHA1 для этих файлов. В настоящее время мой код переносит поток в MD5.Create(). ComputeHash (поток потока), а затем тот же для SHA1. Они, насколько я могу судить, читают файл в 4096-байтовых блоках в буфер, внутренний для хэш-функции, до конца потока.Как я могу вычислить два хэша, не читая один и тот же файл дважды?

Проблема в том, что это один за другим занимает ОЧЕНЬ долгое время! Есть ли способ передать данные в буфер и предоставить буфер для BOTH алгоритмов перед чтением нового блока в буфер?

Пожалуйста, объясните подробно, поскольку я не опытный кодер.

+0

Прочтите его по блоку и подайте данные в свои собственные алгоритмы дайджеста в тандеме – sehe

+0

Проверьте: http://stackoverflow.com/questions/14610850/how-to-get-file-both-md5-and-sha1-checksum- at-the-same-time-when-upload-a-new-fi (java) – PunKeel

+0

Возможный дубликат http://stackoverflow.com/questions/7832440/is-hashalgorithm-computehash-stateful –

ответ

10

Несомненно. Вы можете позвонить TransformBlock несколько раз, а затем TransformFinalBlock в конце, а затем использовать Hash, чтобы получить окончательный хеш. Так что-то вроде:

using (var md5 = MD5.Create()) // Or MD5Cng.Create 
using (var sha1 = SHA1.Create()) // Or SHA1Cng.Create 
using (var input = File.OpenRead("file.data")) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = input.Read(buffer, 0, buffer.Length()) > 0) 
    { 
     md5.TransformBlock(buffer, 0, bytesRead, buffer, 0); 
     sha1.TransformBlock(buffer, 0, bytesRead, buffer, 0); 
    } 
    // We have to call TransformFinalBlock, but we don't have any 
    // more data - just provide 0 bytes. 
    md5.TransformFinalBlock(buffer, 0, 0, buffer, 0); 
    sha1.TransformFinalBlock(buffer, 0, 0, buffer, 0); 

    byte[] md5Hash = md5.Hash; 
    byte[] sha1Hash = sha1.Hash; 
} 

В MD5Cng.Create и SHA1Cng.Create звонков будут создавать обертки вокруг родные реализаций, которые, вероятно, будет быстрее, чем реализации возвращенных MD5.Create и SHA1.Create, но будет немного меньше, портативными (например, для ИХЛ) ,

+0

@GregS: так оно и есть - исправлено, спасибо. –

+0

Perfect :) Я только что протестировал его, и результат согласуется с хешем, созданным моим справочным инструментом (FTK Imager), поэтому я счастлив! –

+0

Если вы вычисляете сразу два хэша, это потому, что вы хотите, чтобы код работал быстро. Таким образом, вы, вероятно, должны использовать MD5Cng.Create() и SHA1Cng.Create(), если вы не поддерживаете Windows XP. Смотрите: http://stackoverflow.com/questions/5341874/which-one-to-use-managed-vs-nonmanaged-hashing-algorithms – 0xdabbad00

Смежные вопросы