Ceci est un projet (?) Provenant de Créer un système de demande de mot de passe (réducteurs de clojure) et dispose d'une gamme réaliste de système de gestion de mot de passe de JAL. C'est une illusion de la méthode qui peut être réalisée avec.
Ne l'appelez pas maintenant ou obsolète.
Veuillez nous faire savoir s'il y a des omissions dans la liste. Je vais l'ajouter.
Un disque qui ne brille pas du tout est ajouté ici.
os:windows7 Home Premium sp1 cpu:i7-4770T @2.50GHz Python:3.4.1(Anaconda 2.0.1 (64-bit))
Puisqu'il s'agit de Python3, il y a du travail pour convertir la chaîne de caractères en une chaîne d'octets. Le processeur a 8 cœurs, mais le nombre de parallèles est de 4. Le code que j'ai utilisé peut être trouvé ici [https://github.com/soyiharu/md5_time_trial).
hash_single.py
import time
import hashlib
import sys
def main():
argv = sys.argv[1:]
if len(argv) != 2:
sys.exit(0)
salt = argv[0]
hash = argv[1]
start = time.time()
for i in range(1000000):
pw = "{0}${1:06d}".format(salt, i).encode("utf-8")
tmp = hashlib.md5(pw).hexdigest()
if hash == tmp:
print("match[{0:06d}]".format(i))
end = time.time()
print("elapsed time:{0}s".format(end - start))
if __name__ == "__main__":
main()
hash_parallel.py
import time
import hashlib
import sys
from multiprocessing import Pool
from itertools import repeat
def calc_hash(arg):
hash, salt, i = arg
tmp = hashlib.md5("{0}${1:06d}".format(salt, i).encode("utf-8")).hexdigest()
return hash == tmp
def main():
argv = sys.argv[1:]
if len(argv) != 2:
sys.exit(0)
salt = argv[0]
hash = argv[1]
start = time.time()
pool = Pool(4)
result = pool.map(calc_hash, zip(repeat(hash), repeat(salt), range(1000000)))
index = result.index(True)
print("match[{0:06d}]".format(index))
end = time.time()
print("elapsed time:{0}s".format(end - start))
if __name__ == "__main__":
main()
Répétez chaque 5 fois pour mesurer le temps.
python hash_single.py hoge 4b364677946ccf79f841114e73ccaf4f
python hash_parallel.py hoge 4b364677946ccf79f841114e73ccaf4f
Première fois | Deuxième fois | Troisième fois | 4e | 5ème fois | moyenne | écart-type | |
---|---|---|---|---|---|---|---|
Version unique | 1.724097967 | 1.736099005 | 1.729099035 | 1.733099937 | 1.739099026 | 1.732298994 | 0.005891065 |
Version multi | 1.086061954 | 1.098062992 | 1.080061913 | 1.113064051 | 1.085062027 | 1.092462587 | 0.013278723 |
L'unité est en secondes
Le temps d'exécution en parallèle est de 63% du non-parallèle ※référence "Arrondi de la valeur de hachage MD5 du mot de passe à 6 chiffres" Lors de l'utilisation d'OpenMP, le résultat de l'exécution (numéro parallèle 4) était de 0,912 s même s'il a été légèrement modifié en fonction de Kita jusqu'à 0,70 seconde. (Code source)
Puisque le temps d'exécution n'est qu'environ 63% en parallélisation, c'est du tout en termes de parallélisation, mais je pense que Python a travaillé dur car j'ai rattrapé la différence d'environ 16% par rapport au cas de c. On peut dire que c est inutile.
J'ai appris l'existence d'un bytearray. La chaîne de caractères python et la chaîne d'octets ne peuvent pas être modifiées, mais le bytearray peut être modifié. En utilisant cela, j'ai pensé que ce serait plus rapide si je ne recréais que la partie du nombre à 6 chiffres sans recréer la chaîne d'octets entière à chaque fois dans la version à un seul thread, mais ce n'était qu'environ 0,1 seconde plus rapide, pas autant que je m'y attendais. fait.
Je publierai les modifications pour que vous puissiez voir ce que vous avez fait.
python
from itertools import product
pw = bytearray("{0}${1:06d}".format(salt, 0).encode("utf-8")) #Préparer bytearray
for i, value in enumerate(product(b'0123456789', repeat=6)):
pw[-6:] = value #Changer uniquement la partie numérique
Après tout, si vous voulez poursuivre la vitesse, peut-être C / C ++.