2009-06-27 10 views
6

Ich bin auf der Suche nach einem C# -Wrapper zu einer nativen MD5 oder SHA1-Bibliothek, um Hash-Rechenleistung zu verbessern.C# schnelle Hash-Berechnung

Bisher habe ich SharpZipLib auf zlib umgestellt und habe mehr als 2x Performance Boost bekommen. (ok, du musst darauf achten, dass du die richtige zlib.so oder zlib.dll hast, abhängig von Betriebssystem und Hardware, aber es zahlt sich aus).

Wird es sich für MD5 oder SHA1 oder .NET und Mono auf eine native Implementierung bereits verlassen?

(Bearbeitet) Auch: falls ich beim MD5CryptoServiceProvider bleiben muss, gibt es eine Möglichkeit, wie ich einen Hash einer Datei berechnen kann, während ich es lese? Ich meine, Bytes in Blöcken senden, aber trotzdem den ganzen Hash berechnen?

+1

Denken Sie daran, dass MD5 ein Cracked Hashing-Algorithmus ist und nicht mehr als sicher gilt. Kollisionen mit SHA1 wurden ebenfalls gefunden, und obwohl sie nicht so schwer wie MD5 waren, wurden sie als signifikante Unterbrechungen angesehen. Wenn Sie einen sicheren Hashalgorithmus benötigen, sollten Sie sich für SHA2-Varianten (256/512) entscheiden. – jrista

+0

@pablo, sind Sie sicher, dass Hashing und nicht IO-Zugriff ist Ihr Engpass ... –

+0

Es kann auch IO sein, du hast recht, aber nach meiner Erfahrung mit zlib, ich habe darüber nachgedacht, ob Switching MD5-Implementierung Dinge beschleunigen würde. – pablo

Antwort

3

Die Klasse SHA1CryptoServiceProvider verwendet die zugrunde liegende Windows-API-Implementierung. Allerdings ist SHA1Managed ziemlich schnell.

EDIT: Ja, es ist möglich, den Hash Schritt für Schritt zu berechnen. Die Methoden TransformBlock und TransformFinalBlock tun dies.

+0

ziemlich schnell kann viele Dinge bedeuten ... entpuppt sich ziemlich schnell bedeutet 3 mal langsamer .... immer noch 30MB pro 300ms ist viel schnell –

0

Ich würde nur die BCL SHA1 und MD5CryptoServiceProvider Klassen verwenden. Diejenigen, die mit dem Framework ausgeliefert werden, sind ziemlich schnell.

+0

Danke. Das ist, was ich gerade benutze, ich frage mich nur, ob es einen Weg gibt, es schneller zu machen. Ich hasse ganze Dateien. – pablo

16

MD5 und SHA1 verlassen sich auf native Implementierungen, nichtsdestoweniger ist es möglich, dass eine C++ Lösung + Introp etwas schneller sein könnte, weil Sie möglicherweise die Anzahl der Methodenaufrufe ein wenig reduzieren und die native Implementierung optimieren können.

Denken Sie daran, dass das Native (SHA1CryptoServiceProvider) 3x schneller sein kann als das gemanagte (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 

auch bedenken es sei denn, meine Berechnung falsch ist, wird die nicht verwaltete Implementierung 100 MB Daten in etwa 300 Millisekunden Hashing, dies wäre sehr selten zu einem Engpass.

+0

Eine Interop-Lösung würde jedoch ein Marshalling erfordern, was andere Vorteile mindern könnte, die andernfalls erzielt werden könnten. Nur etwas, das man im Kopf behalten sollte. – jrista

+0

mein Verständnis ist der SHA1CryptoServiceProvider erfordert Marshalling sowieso, es externe Aufrufe –

+0

Es macht Sinn. – pablo

0

Je nach Ihrer Anwendung des Hashing ist MD5 möglicherweise nicht anwendbar. MD5 ist nur in der Fehlerkorrektur nützlich, es ist nicht länger als eine Überprüfung gegen böswillige Dateiänderung lebensfähig.

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

Die kurze Geschichte ist, MD5-Kollisionen sind einfach durch Ändern 16 Bytes in einer Datei zu erzeugen.