C # быстрый расчет хеша - PullRequest
6 голосов
/ 27 июня 2009

Я ищу оболочку c # для собственной библиотеки MD5 или SHA1, чтобы улучшить производительность вычисления хеша.

Ранее я переключил SharpZipLib на zlib и получил увеличение производительности более чем в 2 раза. (хорошо, вы должны позаботиться о том, чтобы у вас были нужные zlib.so или zlib.dll в зависимости от ОС и оборудования, но это окупается).

Стоит ли для MD5 или SHA1 или для .NET и Mono уже полагаться на собственную реализацию?

(Отредактировано) Кроме того: в случае, если мне нужно придерживаться MD5CryptoServiceProvider, есть ли способ, которым я могу вычислить хэш файла во время чтения? Я имею в виду, отправлять байты кусками, но все равно вычислять весь хэш?

Ответы [ 4 ]

16 голосов
/ 27 июня 2009

MD5 и SHA1 полагаются на собственные реализации, тем не менее, возможно, что решение C ++ + introp может быть немного быстрее, поскольку вы можете немного уменьшить число вызовов методов и оптимизировать собственную реализацию.

Имейте в виду, что Native (SHA1CryptoServiceProvider) может быть в 3 раза быстрее управляемого (SHA1Managed).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography;

namespace ConsoleApplication22 {



    class Program {

        static void Profile(string description, int iterations, Action func) {

            // clean up
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            // warm up 
            func();

            var watch = Stopwatch.StartNew();
            for (int i = 0; i < iterations; i++) {
                func();
            }
            watch.Stop();
            Console.Write(description);
            Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
        }

        static void Main() {
            SHA1Managed managed = new SHA1Managed();
            SHA1CryptoServiceProvider unmanaged = new SHA1CryptoServiceProvider();

            Random rnd = new Random();

            var buffer = new byte[100000];
            rnd.NextBytes(buffer);

            Profile("managed", 1000, () => {
                managed.ComputeHash(buffer, 0, buffer.Length);
            });

            Profile("unmanaged", 1000, () =>
            {
                unmanaged.ComputeHash(buffer, 0, buffer.Length);
            });

            Console.ReadKey();
        }
    }
}
managed Time Elapsed 891 ms
unmanaged Time Elapsed 336 ms

Также имейте в виду , если мои вычисления не верны, неуправляемая реализация хэширует 100 МБ данных примерно за 300 миллисекунд, это очень редко будет узким местом.

3 голосов
/ 27 июня 2009

Класс SHA1CryptoServiceProvider использует базовую реализацию Windows API. Тем не менее, SHA1Managed довольно быстро.

РЕДАКТИРОВАТЬ: Да, можно вычислить хэш шаг за шагом. Для этого используются методы TransformBlock и TransformFinalBlock.

0 голосов
/ 27 июня 2009

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

http://en.wikipedia.org/wiki/Md5#Vulnerability

Коротко говоря, коллизии MD5 легко генерировать, изменяя 16 байтов в файле.

0 голосов
/ 27 июня 2009

Я бы просто использовал классы BCL SHA1 и MD5CryptoServiceProvider . Те, которые поставляются с каркасом, довольно быстрые.

...