Python Forum
Speeding up Brute force password guesser
Thread Rating:
  • 3 Vote(s) - 3.33 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Speeding up Brute force password guesser
#1
Hi, I'm new to python and was wondering how I could speed up my brute force password guesser. I just started python this summer so sorry if it isn't very python-ish

Here's my code:

#imports (im not insulting your inteligence, im just new. :) )

import string, time

#sets printables

var = 3
if var == 1:
   printable = list(string.printable)
   for i in range(5):
       del printable[-1]
elif var == 2:
   printable = list(str(string.ascii_uppercase + string.ascii_lowercase))
elif var == 3:
   printable = list(string.ascii_lowercase)

#variable assignment

password = raw_input("What is the password? -> ")
guess = [printable[0]]
place = 0
limit = 8
correct = False

#sees if the current guess is correct, returns true if so

def ispass():
   if "".join(guess) == password:
       return True
   else:
       return False

#reverts all elements of guess list to first element of printables

def zitup():
   for i in range(len(guess)):
       guess[i] = printable[0]
   guess.append(printable[0])

#moves inncorrect guess to the next string

def next():
   if guess[place] == printable[-1]:
       guess[place] = printable[0]
   else:
       try:
           guess[place] = printable[printable.index(guess[place])+1]
       except ValueError:
           print(guess, place)
#if ispass() returns false detects if all elements of guess are the last element of printable, if so exicutes zitup(), else sets the next non last element of printables to the next possible element

while len(guess) < limit:
   correct = ispass()
   if correct:
       break
   else:
       place = len(guess)-1
       while guess[place] == printable[-1] and place > -1:
           guess[place] = printable[0]
           place += -1
       if place < 0:
           zitup()
           print("Char added")
       else:
           next()

#prints correct guess, or incorrect if len(guess) exceded limit

print("The password is: " + "".join(guess))
Reply
#2
Hello!
Look at concurrent.futures. The ProcessPoolExecutor class.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#3
(Jul-19-2017, 10:39 AM)Gamervote Wrote: def ispass():
  if "".join(guess) == password:
      return True
  else:
      return False

You don't need the if blocks...
def ispass():
   return "".join(guess) == password
But that's besides the point.  There's a pretty cool profiler included in the standard lib, which can help narrow down where you should focus on improvement: https://docs.python.org/3.6/library/profile.html

As a demo, I changed your program slightly so that the while loop at the end is a function, and then I call that function with the profiler.
The code:
# imports (im not insulting your inteligence, im just new. :) )

import string
import time

# sets printables

var = 3
if var == 1:
   printable = list(string.printable)
   for i in range(5):
       del printable[-1]
elif var == 2:
   printable = list(str(string.ascii_uppercase + string.ascii_lowercase))
elif var == 3:
   printable = list(string.ascii_lowercase)

# variable assignment

password = input("What is the password? -> ")
guess = [printable[0]]
place = 0
limit = 8
correct = False

# sees if the current guess is correct, returns true if so


def ispass():
   if "".join(guess) == password:
       return True
   else:
       return False

# reverts all elements of guess list to first element of printables


def zitup():
   for i in range(len(guess)):
       guess[i] = printable[0]
   guess.append(printable[0])

# moves inncorrect guess to the next string


def next():
   if guess[place] == printable[-1]:
       guess[place] = printable[0]
   else:
       try:
           guess[place] = printable[printable.index(guess[place]) + 1]
       except ValueError:
           print(guess, place)
# if ispass() returns false detects if all elements of guess are the last element of printable, if so exicutes zitup(), else sets the next non last element of printables to the next possible element


place = 0


def find_password():
   global place

   while len(guess) < limit:
       correct = ispass()
       if correct:
           break
       else:
           place = len(guess) - 1
           while guess[place] == printable[-1] and place > -1:
               guess[place] = printable[0]
               place += -1
           if place < 0:
               zitup()
               print("Char added")
           else:
               next()

import cProfile
cProfile.run("find_password()")

# prints correct guess, or incorrect if len(guess) exceded limit
print("The password is: " + "".join(guess))
Output:
What is the password? -> spam Char added Char added Char added         2068813 function calls in 0.767 seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.000    0.000    0.767    0.767 <string>:1(<module>)        6    0.000    0.000    0.000    0.000 cp437.py:18(encode)   344799    0.094    0.000    0.137    0.000 eggs.py:29(ispass)        3    0.000    0.000    0.000    0.000 eggs.py:35(zitup)   344795    0.193    0.000    0.312    0.000 eggs.py:43(next)        1    0.284    0.284    0.767    0.767 eggs.py:57(find_password)        6    0.000    0.000    0.000    0.000 {built-in method _codecs.charmap_encode}        1    0.000    0.000    0.767    0.767 {built-in method builtins.exec}   689600    0.033    0.000    0.033    0.000 {built-in method builtins.len}        3    0.000    0.000    0.000    0.000 {built-in method builtins.print}        3    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}   344795    0.119    0.000    0.119    0.000 {method 'index' of 'list' objects}   344799    0.043    0.000    0.043    0.000 {method 'join' of 'str' objects} The password is: spam
I don't have the patience to wait for a 5 character input, but we can already see that there are a massive number of calls to ispass() and next(), which take up most of the running time.  Those functions aren't terribly complicated, which means the focus of improvement shouldn't be on making those functions better, but instead should focus almost entirely on having less loops.  Specifically, if you can get rid of the while loop that's within the while loop, you'd likely see much better performance.
Reply
#4
Thannks for your help but I'm comfused on one thing, is it the fact that there is a nested while loop that is making the program so slow while "cracking" 5+ digit passwords, or is it because the functions ispass() and next() are called so much?
Reply
#5
Both? A nested loop by itself doesn't mean anything, but it's because of the loop that you're calling the functions so much.

If I were to take a guess at a better way to do it (again, this is a guess, I haven't actually tried this or tested it or anything), I would generate all possible passwords that are X characters long, test them, and then do it again for X+1 characters long, and keep increment X until I hit paydirt. That way, you can use itertools to generate the combinations (https://docs.python.org/3.6/library/iter...ls.product).
Reply
#6
For example, let's rewrite your program to use itertools.  If there's no other benefit, I hope you'd agree that it's at least easier to read (and much shorter), which is a nice benefit, but is unrelated to speed.

import itertools
import string
import time

var = 3
if var == 1:
   printable = list(string.printable)
   for i in range(5):
       del printable[-1]
elif var == 2:
   printable = list(str(string.ascii_uppercase + string.ascii_lowercase))
elif var == 3:
   printable = list(string.ascii_lowercase)
password = input("What is the password? -> ")


def ispass(guess):
   return "".join(guess) == password


def find_password():
   attempt_length = 0
   while True:
       attempt_length += 1
       guesses = itertools.product(printable, repeat=attempt_length)
       for guess in guesses:
           if ispass(guess):
               return guess
       print("char added")


#guess = find_password()


import cProfile
cProfile.run("guess = find_password()")


# prints correct guess, or incorrect if len(guess) exceded limit
print("The password is: " + "".join(guess))
The profiler gives us this:
Output:
What is the password? -> spam char added char added char added         689617 function calls in 0.165 seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.000    0.000    0.165    0.165 <string>:1(<module>)        6    0.000    0.000    0.000    0.000 cp437.py:18(encode)   344799    0.072    0.000    0.106    0.000 eggs.py:17(ispass)        1    0.058    0.058    0.165    0.165 eggs.py:21(find_password)        6    0.000    0.000    0.000    0.000 {built-in method _codecs.charmap_encode}        1    0.000    0.000    0.165    0.165 {built-in method builtins.exec}        3    0.001    0.000    0.001    0.000 {built-in method builtins.print}        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}   344799    0.034    0.000    0.034    0.000 {method 'join' of 'str' objects} The password is: spam
This is much faster (0.767 seconds down to 0.165 seconds).  Now we see that the ispass() function and the inbuilt str.join() methods are the big hogs.  So, let's rewrite the ispass() function to avoid calling str.join...

# convert it to a tuple
# "spam" => ("s", "p", "a", "m")
password = tuple(password)


def ispass(guess):
   return guess == password
Output:
What is the password? -> spam char added char added char added         344818 function calls in 0.091 seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.000    0.000    0.091    0.091 <string>:1(<module>)        6    0.000    0.000    0.000    0.000 cp437.py:18(encode)   344799    0.035    0.000    0.035    0.000 eggs.py:21(ispass)        1    0.055    0.055    0.091    0.091 eggs.py:25(find_password)        6    0.000    0.000    0.000    0.000 {built-in method _codecs.charmap_encode}        1    0.000    0.000    0.091    0.091 {built-in method builtins.exec}        3    0.001    0.000    0.001    0.000 {built-in method builtins.print}        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects} The password is: spam
BOOM!  Now it's fast enough for us to do 5 character passwords without hating our life too much...
Output:
What is the password? -> spams char added char added char added char added         8964817 function calls in 2.255 seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.000    0.000    2.255    2.255 <string>:1(<module>)        8    0.000    0.000    0.000    0.000 cp437.py:18(encode)  8964793    0.859    0.000    0.859    0.000 eggs.py:21(ispass)        1    1.395    1.395    2.255    2.255 eggs.py:25(find_password)        8    0.000    0.000    0.000    0.000 {built-in method _codecs.charmap_encode}        1    0.000    0.000    2.255    2.255 {built-in method builtins.exec}        4    0.001    0.000    0.001    0.000 {built-in method builtins.print}        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects} The password is: spams
There's a few other things we can do, but that's all I've got time for now.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Need an alternative to brute force optimization loop jmbonni 5 1,171 Dec-07-2023, 12:28 PM
Last Post: RockBlok
  Speeding up code using cache Peter 1 536 Jul-29-2023, 04:52 AM
Last Post: bowlofred
  Solving an equation by brute force within a range alexfrol86 3 2,774 Aug-09-2022, 09:44 AM
Last Post: Gribouillis
  force a program to exit ? Armandito 3 2,512 May-12-2022, 04:03 PM
Last Post: Gribouillis
  How to use scipy.optimization.brute for multivariable function Shiladitya 9 6,184 Oct-28-2020, 10:40 PM
Last Post: scidam
  best way to force an exception Skaperen 2 2,056 Oct-21-2020, 05:59 AM
Last Post: Gribouillis
  I need advise with developing a brute forcing script fatjuicypython 11 5,049 Aug-21-2020, 09:20 PM
Last Post: Marbelous
  Force calculation result as decimal vercetty92 4 2,852 Mar-20-2019, 02:27 PM
Last Post: vercetty92
  Password Brute Force 2skywalkers 9 5,344 Oct-18-2018, 02:35 PM
Last Post: buran
  Brute Force Password Guesser 2skywalkers 1 3,172 Oct-05-2018, 08:04 PM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020