2010-02-10 5 views
12

Il modulo hashlib Python fornisce i seguenti algoritmi di hash costruttori: md5(), sha1(), sha224(), sha256(), sha384() e sha512().C'è un overhead significativo utilizzando diverse versioni di sha di hashing (modulo hashlib)

Supponendo che non voglio usare md5, c'è una grande differenza nell'usare, per esempio, sha1 invece di sha512? Voglio usare qualcosa come hashlib.shaXXX(hashString).hexdigest(), ma siccome è solo per il caching, non sono sicuro di aver bisogno del (eventuale) sovraccarico di 512 ...

Questo sovraccarico esiste, e se sì, quanto è grande ?

+2

Se è per il caching, perché è necessario un hash sicuro? –

+4

Quando hai provato i diversi metodi e misurato le loro prestazioni, che cosa hai trovato? –

+2

Ciò che probabilmente intendeva dire @GregHewgill è che esiste un comodo 'timeit' del modulo di libreria standard che rende tali misurazioni così banali che è più semplice dedicare solo il tempo che chiedere, specialmente quando viene eseguito dalla riga di comando. –

risposta

18

Perché non limitarlo al benchmark?

>>> def sha1(s): 
...  return hashlib.sha1(s).hexdigest() 
... 
>>> def sha512(s): 
...  return hashlib.sha512(s).hexdigest() 
... 
>>> t1 = timeit.Timer("sha1('asdf' * 100)", "from __main__ import sha1") 
>>> t512 = timeit.Timer("sha512('asdf' * 100)", "from __main__ import sha512") 
>>> t1.timeit() 
3.2463729381561279 
>>> t512.timeit() 
6.5079669952392578 

Quindi sulla mia macchina, hash512 è due volte più lento come sha1. Ma come ha detto GregS, perché dovresti usare un hash sicuro per il caching? Provate gli algoritmi di hash incorporate che dovrebbero essere veramente veloce e messo a punto:

>>> s = "asdf" 
>>> hash(s) 
-618826466 
>>> s = "xxx" 
>>> hash(s) 
943435 
>>> hash("xxx") 
943435 

O meglio ancora, utilizzare i dizionari Python builtin. Forse puoi dirci di più su cosa pensi di fare il caching.

EDIT: sto pensando che si sta cercando di realizzare qualcosa di simile a questo:

hash = hashlib.sha1(object_to_cache_as_string).hexdigest() 
cache[hash] = object_to_cache 

Quello che stavo refferring a da "utilizzare i dictinoaries Python builtin" è che si può semplificare il sopra :

cache[object_to_cache_as_string] = object_to_cache 

In questo modo, Python si occupa dell'hashing in modo da non doverlo fare!

Per quanto riguarda il problema specifico, è possibile fare riferimento a Python hashable dicts per rendere un dizionario lavabile. Poi, tutto quello che avresti bisogno di fare per memorizzare nella cache l'oggetto è:

cache[object_to_cache] = object_to_cache 
+0

Grazie per aver dedicato del tempo per confrontarlo. Come molti di voi hanno detto, probabilmente non ho bisogno di usare l'hashing sicuro per il caching. Fondamentalmente ho bisogno di memorizzare un'impronta digitale del [contenuto di] un dizionario.Siccome non posso usare "hashlib" o "hash()" direttamente su un dizionario, stavo costruendo una stringa contenente gli elementi di quel dizionario (non mi piace questo approccio) e poi uso "hashlib" su di esso .. Ma ora mi hai incuriosito con "usa i dizionari Python incorporati", cosa intendi con questo? – Emilien

+0

Vedi modifica. Spero che questo risolva il tuo problema. – sttwister

+0

Leggendo i tuoi commenti (tutti voi), mi sono reso conto che non avevo bisogno di usare un hashing sicuro, quindi ho implementato il mio algoritmo di "hashing". Dato che il dizionnario ha sempre degli elementi specifici, e ogni valore ha un'idea, creo una stringa da quelle idee e la memorizzo in cache. Ringrazia tutti. – Emilien

3

Forse un test ingenuo ... ma sembra che dipende da quanto si sta hashing. 2 blocchi di sha512 sono più veloci di 4 blocchi di sha256?

>>> import timeit 
>>> import hashlib 
>>> for sha in [ x for x in dir(hashlib) if x.startswith('sha') ]: 
... t = timeit.Timer("hashlib.%s(data).hexdigest()" % sha,"import hashlib; data=open('/dev/urandom','r').read(1024)") 
... print sha + "\t" + repr(t.timeit(1000)) 
... 
sha1 0.0084478855133056641 
sha224 0.034898042678833008 
sha256 0.034902095794677734 
sha384 0.01980900764465332 
sha512 0.019846916198730469 
+0

Ho ottenuto risultati simili. Penso che l'apprendimento di fatto qui sia che md5 e sha1 sono simili nella velocità (ho anche messo a confronto md5 usando questo metodo) e quindi sha512 è più veloce di tutti gli hash in mezzo. Pertanto, usa sha1 per speed e sha512 per un hashing migliore. Gli altri non hanno senso dal punto di vista delle prestazioni. –

+0

ho ottenuto risultati molto diversi, forse la realizzazione o macchine sono meglio ottimizzati corrente: 'sha1':' '0.00902104377746582' sha224':' '0.007354021072387695' sha256':' '0.007508993148803711' sha384':' '0.004772186279296875' sha512 ':' 0,004884004592895508' – Medorator