0

I have made a basic password cracking program which tells the user in what time a basic hit and trial algorithm can crack their password.But I am getting a memory error when I am running the program, I also tried to do with adding all the data to sqlite file but that is also not working.Please help me.

My code:

from random import *
import time
import itertools
from string import *

class password_cracker():

    result = 0
    pswd_db = []

    def __init__(self,n):
        self.n  = n
    def input_phase(self):
       self.n = input("Password: ")
    def cracker(self):
        data_stock = ascii_letters + digits + punctuation
        pswd = ''
        combs = list(itertools.permutations(data_stock, 6))  #I am getting the error here
        start = time.time()
        for byts in combs:
            for bits in byts:
                pswd += bits
            pswd_db.append(pswd)
            if pswd == self.n:
                result = 1
                break
            else:
                result = 0
            pswd = ''
        end = time.time()
        total_time = end - start


    def final_result(self):
        if result == 0:
            print('You have got an exceptional password!')
        else:
            print('Password cracked in ', total_time)

 n =  password_cracker("")
 n.cracker()  

In console:

Traceback (most recent call last): File "c:/Users/Soumodeep Bhowmick/Desktop/CS.IP/pws.py", line 93, in n.cracker() File "c:/Users/Soumodeep Bhowmick/Desktop/CS.IP/pws.py", line 59, in cracker combs = list(itertools.permutations(data_stock, 6)) MemoryError

Kalana
  • 5,631
  • 7
  • 30
  • 51

2 Answers2

3

On that line:

combs = list(itertools.permutations(data_stock, 6))

You are asking for a list of all the length 6 permutations of data_stock (which is 94 characters long). So, that's a list of 94 ^ 6 (or 94! / 88! if you expected combinations) strings of 6 characters long. Or, put simply, a list of 689,869,781,056 or 586,236,072,240 strings of 6 characters.

If you use an iterator instead, you won't run out of memory, but your script will be busy for a while... You may want to consider another approach altogether.

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • How to use a generator can you pls give the code for that? – Soumodeep Bhowmick Jan 16 '20 at 05:25
  • Other people have already answered that question, just remove `list()` as `itertools.permutations` returns a iterator, which amounts to the same in this case. – Grismar Jan 16 '20 at 05:27
  • 1
    @Grismar terminology nitpick:`itertools.permutations` does not return a generator, it returns an *iterator* – juanpa.arrivillaga Jan 16 '20 at 05:27
  • For those interested, you can read about the differences between an iterator and a generator [here](https://stackoverflow.com/questions/2776829/difference-between-pythons-generators-and-iterators) – PeptideWitch Jan 16 '20 at 05:40
2

That list call takes in the entire list of 6-element strings into memory. You should just be able to remove the list call:

combs = itertools.permutations(data_stock, 6)
for comb in combs:
    ...

This will generate each permutation only as it's needed--only one will be stored in memory at a time. As a rule of thumb, the stuff in the itertools module naturally returns iterators, which are designed to be consumed by for-loops.

Dennis
  • 2,249
  • 6
  • 12