Performance: hash, md5, sha, hmac...

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich wollte mal wissen, wie schnell die verschiedenen Hash Funktionen in Python v2.4 sind.
hmac kann man eigentlich ganz vergessen. Der ist so langsam das es keinen Sinn macht, diesen mit zu testen. Ansonsten dauert es ewig oder man muß die loop Anzahl so niedrig einstellen, das die anderen Tests keinen Sinn machen. Probiert es mal selber:

Code: Alles auswählen

import timeit, os, string

loop = 500000

TEST_STRING = string.ascii_letters + string.digits

tests = (
    ("hash('%s')" % TEST_STRING, ""),
    ("md5.new('%s').hexdigest()" % TEST_STRING, "import md5"),
    ("sha.new('%s').hexdigest()" % TEST_STRING, "import sha"),
    #~ ("hmac.new('%s').hexdigest()" % TEST_STRING, "import hmac"),
)

for no, test in enumerate(tests):
    print "%s - %s" % (no+1, test[0])

    test = timeit.Timer(test[0], test[1])
    print "%.2f" % test.timeit(number=loop)

    print
Ergebnis:
1 - hash('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
Test: 0.09

2 - md5.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
Test: 0.83

3 - sha.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
Test: 0.99
Die Python hash() Funktion ist also ungeschlagen. Leider dürften damit aber recht schnell Kollisionen auftreten ;(

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Es scheint du hast nicht ganz verstanden was ein hmac ist,
Sieh dir mal das an:
http://de.wikipedia.org/wiki/HMAC

Und zu Python Hash Funktion, ich nehme mal stark an das diese nicht entwickelt wurde um Kryptographisch brauchbar zu sein.
BlackJack

@jens: Der erste Test misst nicht Berechnung des Zeichenketten-Hashwertes, sondern nur wie schnell eine Methode aufgerufen werden kann, die eine Konstante zurück gibt. `hash()` ruft `str.__hash__()` auf und da Zeichenketten immutabel sind, wird deren Hashwert *einmal* beim erzeugen der Zeichenkette, hier also beim kompilieren, berechnet.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

@veers: Ehrlich gesagt, hab ich mir wirklich nicht hmac angesehen :oops:

@BlackJack: Hm. Dann müsste ich den Test-String dynamisch erzeugen... Ob es reicht ein eval() zu machen ? Naja... Egal...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Du kannst ja noch ``binascii.crc32`` benchmarken, für einige Anwenungsfälle ist das auch brauchbar.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

ok, hier:

Code: Alles auswählen

import timeit, os, string

loop = 700000

TEST_STRING = string.ascii_letters + string.digits

tests = (
    ("md5.new('%s').hexdigest()" % TEST_STRING, "import md5"),
    ("sha.new('%s').hexdigest()" % TEST_STRING, "import sha"),
    ("binascii.crc32('%s')" % TEST_STRING, "import binascii"),
)

for no, test in enumerate(tests):
    print "%s - %s" % (no+1, test[0])

    test = timeit.Timer(test[0], test[1])
    print "%.2f" % test.timeit(number=loop)

    print
Ausgaben:
1 - md5.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
1.18

2 - sha.new('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789').hexdigest()
1.39

3 - binascii.crc32('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
0.57
Also binascii.crc32 ist am schnellsten. Allerdings ist es auch nur eine 32-bit checksum ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten