Für ein aktuelles Projekt im privaten Umfeld muss ich eine große Anzahl an MD5-Hashes erzeugen. Platz für Diskussion über Sinnhaftigkeit und Sicherheit von MD5-Hashes möchte in diesem Artikel ausdrücklich nicht geben, sondern mich viel mehr damit beschäftigen, wie sich mittels C# möglichst schnell MD5-Hashes generieren lassen.
Das .NET-Framework selbst bringt eine Klasse zum Erstellen von MD5-Hashes mit sich, welche mir nach ersten Versuchen jedoch etwas langsam vorkam. Somit habe ich mich auf die Sache nach alternativen Klassen und/oder Funktionen gemacht und bin auf eine Klasse von Syed Faraz Mahmood gestoßen. Hierbei handelt es sich um eine manuelle Implementierung seinerseits der RFC 1321 („The MD5 Message-Digest Algorithm“). Die Klasse kann kostenlos auf seinem Blog heruntergeladen werden.
Die Testumgebung
Für den Test habe ich 6 Listen (List<int>) mit verschieden vielen Zahlen erstellen. Je eine mit 1.000, 10.000, 50.000, 100.000, 1.000.000 und 10.000.000 Elementen.
Alle Listen wurden für beide Methoden (.NET-Framework MD5 Implementierung & manuelle MD5 Implementierung) komplett durchlaufen und jedes Element der jeweiligen Liste wurde gehasht. Hierbei wurde der Zeit für die jeweiligen Listendurchläufe gemessen und in einer Grafik aufgetragen, um die Ergebnisse besser auswerten zu können.
Den Quellcode meiner Testumgebung könnt ihr euch entweder auf Github anschauen oder das Visual Studio Projekt direkt hier von meinem Blog herunterladen.
Benchmark – Die Ergebnisse
Wie sich den Grafiken entnehmen lässt, ist die manuelle Implementierung im Schnitt 2/3 schneller als die Implementierung des .NET-Frameworks.
Auch lässt sich festhalten, dass dieser Geschwindigkeitsvorteil konstant ist. So bleibt es bei dem 1/3 der benötigten Zeit auch bei großen Listen. Ein Einbruch der Performance bei Veränderung der Listengröße war nicht zu beobachten.
Ich für meinen Teil, werde in für zukünftige Projekt auf die Implementierung von Syed Faraz Mahmood zurückgreifen und möchte an dieser Stelle auch noch mal herzlichst Danke sagen, für die tolle Arbeit, die er da geleistet hat.
Eure Erfahrungen?
Habt ihr euch auch schon mit diesem Thema beschäftigt oder selbst schon einmal einen Algorithmus zur Erzeugung von MD5-Hashes implementiert? Haltet ihr meinen Test für repräsentativ oder habt ihr noch Verbesserungsvorschläge? Feedback ist immer gern gesehen!
Maybe in the future it’ll do even better in those areas, but for now it’s a fantastic way to organize and listen to your music and videos, and is without peer in that regard. The iPod’s strengths are its web browsing and apps.
Schön gestalteter Vergleich. Mich wundert allerdings, dass Du MD5 Hashs als eindeutige Identifizierer nimmst.
Wie wäre es mit einem global unique identifier – kurz GUID? GUIDs sind noch einmal wesentlich schneller. https://github.com/SchadLucas/MD5PerformanceTest
Hallo Lucas,
danke für den Hinweis. GUIDs sind an sich eine gute Idee. Wenn es aber um den Aufbau einer Hashtable geht, nützen Sie mir nicht viel. Nehmen wir an, ein Element kommt doppelt vor. Beim Hashing erhalte ich den identischen Hash und weiß, dass ich das Element nicht in den Datenbestand übernehmen muss, da es bereits existiert. Das geht mit GUIDs leider nicht.
Prinzipiell ist also aus dem Anwendungsfall heraus zu entscheiden, ob ein Hashverfahren oder GUID mehr Sinn machen.
Hi Raffi,
Du könntest via LINQ relativ simpel das Gleiche erreichen und hättest höchstwahrscheinlich immer noch einen wesentlichen Geschwindigkeitsvorteil. Give it a try ;-)
MD5 Hashes sollte man nur noch dort einsetzen, wo Sicherheit kein Thema ist. Zur Speicherung von Passwörtern sollte man sie nicht mehr verwenden, da md5 inzwischen gebrochen wurde.
Lesenswert hierzu: http://www.schnatterente.net/webdesign/passwoerter-sicher-speichern
Ansonsten ein schönes Artikel! :)
Deswegen sagte ich ja auch extra, dass das Thema Sicherheit nicht in diesem Artikel diskutiert werden würde. Für Hashtables, Zuordnung, etc. kann man MD5 immer noch gut nutzen. ;)
Viele Grüße
Jop, hatte ich auch gelesen – war nur verwundert, dass du md5 überhaupt dafür nimmst. Die meisten Leute gehen dazu über den Alg. einfach zu verbannen und für alle Zwecke Sha und Co. einzusetzen.
Kommt immer darauf an, was man vorhat. Wenn man nur einen eindeutigen “Schlüssel” generieren will (ja, es sind Kollisionen in MD5 nachgewiesen, aber das vernachlässigen wir an dieser Stelle mal), dann ist MD5 ganz zügig. Und ich bin auch der Überzeugung, dass MD5 etwas effizienter ist als SHA. Siehe auch hier: http://stackoverflow.com/questions/2722943/is-calculating-an-md5-hash-less-cpu-intensive-than-sha-1-or-sha-2