2011-01-19 4 views
1

В проекте C#, над которым я сейчас работаю, мы пытаемся вычислить MD5 большого количества файлов по сети (текущий банк равен 2,7 миллиона, клиентский банк может превысит 10 миллионов). С количеством файлов, которые мы обрабатываем, скорость возникает.C# Высокоскоростной MD5/SHA хэш по сети

Причина, по которой мы делаем это, заключается в проверке того, что файл был скопирован в другое место без изменений.

В настоящее время мы используем следующий код для вычисления MD5 файла

MD5 md5 = new MD5CryptoServiceProvider(); 
StringBuilder sb = new StringBuilder(); 

byte[] hashMD5 = null; 

try 
{ 
    // Open stream to file to get MD5 hash for, create hash 
    using (FileStream fsMD5 = new FileStream(sFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     hashMD5 = md5.ComputeHash(fsMD5); 
} 
catch (Exception ex) 
{ 
    clsLogging.logError(clsLogging.ErrorLevel.ERROR, ex); 
} 

string md5sum = ""; 
if (hashMD5 != null) 
{ 
    // Change hash into readable text 
    foreach (byte hex in hashMD5) 
     sb.Append(hex.ToString("x2")); 
    md5sum = sb.ToString(); 
} 

Однако скорость это не то, что мой менеджер надеялись. Мы внесли ряд изменений в способ и количество файлов, которые мы вычисляем для MD5 (т. Е. Мы не делаем это для файлов, которые мы не копируем ... до сегодняшнего дня, когда мой менеджер передумал вСЕХ файлы должны иметь MD5, рассчитанные для них, в случае, если в каком-то момент в будущем клиент хочет убраться с нашей программой, так что все файлы копируются я думаю)

Я понимаю, что скорость сети, вероятно, является основной (100 Мбит/с). Есть ли эффективный способ вычисления MD5 содержимого файла по сети?

Заранее спасибо. Trevor Watson

Редактировать: поместить весь код в блок, а не только его часть.

+0

Есть ли причина, по которой вы не можете проверить хеши на локальном компьютере, на который были скопированы файлы? – arootbeer

+0

Первым пунктом бизнеса является определение узкого места. Запустили ли вы какие-либо тесты, чтобы узнать, насколько быстро процесс занимает просто чтение файла и повторение, поскольку вы не вычисляете хэш? Затем с хешем; сколько накладных расходов приходится на вычисление? Вы выполняли одну и ту же задачу локально? –

+0

Я согласен с Аароном: время, необходимое для вычисления хэша, - это сумма: открытие удаленного файла по сети, поиск начала на диске, чтение с диска, потоковое содержимое по сети, вычисление хэша. Любой из них может вызвать узкое место. Некоторые из них могут быть сделаны параллельно для разных файлов, как предложил Эндрю Купер. – wigy

ответ

3

Узким является то, что весь файл должен быть потоковым/скопирована по сети, и ваш, кажется, хорошо выглядеть ... различные хеш-функции (md5/SHA256/SHA512) имеют почти то же самое время вычисления

Два возможных решения этой проблемы:

1) запустите хэшер в удаленной системе и сохраните хэши для разделения файлов - если это возможно в вашей среде.

2) Создайте мужественный хэш файла, чтобы вы копировали только часть файла. Я имею в виду что-то вроде этого:

part1Hash = md5(file.getXXXBytesFromFileAtPosition1) 
part2Hash = md5(file.getXXXBytesFromFileAtPosition2) 
part3Hash = md5(file.getXXXBytesFromFileAtPosition3) 
finalHash = part1Hash^part2Hash^part3Hash; 

вы должны проверить, какая часть файла являются оптимальными для чтения, поэтому хэш оставаться уникальными.

надежда, что помогает ...

редактировать: изменены побитовому XOR

+1

. При объединении хэшей вам будет намного лучше использовать бит-мудрый XOR. Использование OR приведет к хешу со многими более 1-ю, чем к 0, и к гораздо большему шансу столкновения хэшей. –

+0

@andrew: спасибо, изменил его. – CaptainPlanet

+0

Если вы не можете установить что-то на стороне клиента, перейдите сюда с №2. Пропускная способность - ваш враг здесь, тем более, что 100MBit/s является только теоретическим и не учитывает других людей в сети. Теоретически возможно, чтобы кто-то нарушил этот тип алгоритма, но если они это сделают, вы можете сообщить об этом в NSA, и они будут отобраны. Прочитайте пару блоков байтов и хэш их. Чем больше байтов, тем лучше, но вам нужно настроить на основе производительности. –

1

Почему бы вам не попробовать установить «клиент» на каждом из них, который прослушивает порт и когда сигнализирует, рассчитает хэш MD5 для запрошенных файлов.

Теперь основному серверу нужно будет спросить каждого клиента рассчитать MD5. Используя этот распределенный подход, вы получите общую скорость всех клиентов и уменьшите перегрузку сети.

+0

Это не сработает, если файловый сервер является устройством NAS с собственной ОС. –

+0

Для каждого устройства в сети держите флаг, чтобы проверить, есть ли у него клиент. Если это так, используйте это, иначе используйте текущий подход ... Я знаю, что это становится сложным и имеет свои проблемы, но это поможет как скорости, так и сети. – andrewjs

+0

Спасибо за все ваши советы. Мы пытаемся посмотреть на создание программы для вычисления значений хэша на клиентских машинах. Надеюсь, это даст нам способ сделать это. И мы могли бы использовать мощность обработки этих машин для файлов по пути UNC, а также –

3

Один из возможных подходов было бы использовать параллельную библиотеку задач в .Net 4.0. 100 Мбит/с по-прежнему будет узким местом, но вы должны увидеть небольшое улучшение.

В прошлом году я написал небольшое приложение, которое просматривает верхние уровни дерева папок, проверяя папки и параметры безопасности файлов. Запустив более 10 Мбит/с WAN, потребовалось около 7 минут, чтобы завершить один из наших больших файлов.Когда я распараллеливал операцию, время выполнения сократилось чуть более 1 минуты.

+0

У нас, к сожалению, нет доступа к библиотеке .NET 4.0. Я могу попытаться увидеть, создает ли несколько потоков для вычисления хэш-значения файла в кусках. Я видел сообщение здесь о хэшировании частей файла, чтобы получить MD5 всего файла. –

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