# SHA256 password cracker - brute force

I wrote a SHA256 password cracker. I initially used lists to store the information in list1.txt and list2.txt but I would end up getting memory overloads. So I now use files. I noticed that when I made this transition, the programme speed reduced hugely. Is there a way to optimise the speed of this programming without running into memory overload issues?

Thanks

import hashlib
import time
import os

if fname == 0:
filename = "list2.txt"
else:
filename = "list1.txt"
for line in open(filename, "r"):
yield line.strip()

if fname == 0:
filename = "list1.txt"
else:
filename = "list2.txt"

file = open(filename, "a")
file.write("\n")
file.close()

found = 0
guess = item + chr(next_char)
print(guess)
found = 1
return found

pwrd = pwrd.encode("UTF-8")

def delete_file(ltsa):
try:
if ltsa == 1:
os.remove("list2.txt")
else:
os.remove("list1.txt")
except:
pass

def reset_file_status():
try:
os.remove("list2.txt")
os.remove("list1.txt")
except:
pass

#Brute force to find original password
found = 0
lsta = 1
for length in range(1, 15):
if found == 1: break
lsta = lsta^1
delete_file(lsta)
for next_char in range(65, 123):
if found == 1: break
if length == 1:
if found == 1: break
else:
if found == 1: break

if __name__ == "__main__":
reset_file_status()
start = time.time()
print(f"{(time.time() - start)} seconds")

• This appears to be Python 3, is that correct? Nov 16, 2020 at 2:49
• Yes. This is python 3
– EML
Nov 16, 2020 at 9:44

The optimization you are looking for is very simple:

There is no need to store all the old guesses, so there is no need for files or huge lists.

All you really need is one string you will keep updating.

To visualize this, think of your string as a growing number, with each letter being a base 58 digit.

Now. all you really need is to do a +1 on the first digit, checking for carry and updating following digits if needed just like usual addition.

Unfortunately, Python strings don't allow assignment by index, but they do support slicing.

Here is a function that would generate sequential passwords running through all the letters and growing the length as needed (one password per call!):

def make_next_guess(guess):
carry = 1
next_guess = guess

for i in range(len(guess)):
cur_char = ord(guess[i]) + carry
if cur_char > ord('z'):
cur_char = ord('A')
carry = 1
else:
carry = 0

next_guess = next_guess[:i] + chr(cur_char) + guess[i + 1:]
if carry == 0:
break

if carry = 1:
next_guess += 'A'

return next_guess


With this you can use one loop for all the possibilities up to the maximum length:

guess = 'A'

for _ in range(58 ** 14): #password maximum length 14 and there are 58 characters that can be used