Joshua Jackson Joshua Jackson - 1 month ago 10
Python Question

Implementing a loop to cycle through letter and number combinations?

This is my first question, so hopefully I do this right. I'm working on a project that 'guesses' a password that is input by the user. The program already knows the password, but what I'm trying to have it do is have it cycle through all possible combinations of characters according to what type of password it is. The program also looks for if the password is numeric, alphanumeric, or is alphanumeric and contains special characters.

I haven't had much trouble so far with it (it can successfully figure out a numeric password) but after trying for several hours to configure an alphanumeric guessing feature, I've decided to turn for some help.

My question is: How should I go about implementing this? I've attached my program, which is split into two files. main.py is the file you're supposed to run. Lines 43 to 75 in Guesser.py are the problem area. I'm relatively new to Python, and this is the largest scale project I've done, so I'd appreciate any suggestions or changes to the design! (Let me know if anything doesn't make sense)

MAIN.PY

import string
import Guesser
letters = list(string.printable)
del(letters[94:100])
class Main():
def __init__():
qst = input('One password (1) or multiple (m)? ')
if qst == '1':
pss = input('Password: ')
if len(pss) < 4:
print('Error! Password too short!')
Main.__init__()
elif len(pss) > 15:
print('Error! Password too long!')
Main.__init__()
else:
pass
Main.type_check(qst, pss)
else:
e = 0
print('Type \'done\' if you have typed in all of your passwords')
plist = list()
c = True
while c == True:
e = e + 1
i = input('Password %s: ' % e)
i.replace('\n', '')
if len(i) < 4:
print('Error! %s is too short.' % i)
Main.__init__()
elif len(i) > 15:
print('Error! %s is too long.' % i)
Main.__init__()
if i != 'done':
plist.append(i)
else:
c = False
pss = plist
Main.type_check(qst, pss)
def type_check(qst, pss):
if qst == '1':
try:
int(pss)
pass_type = 'num'
Guesser.Guesser.check(pss, pass_type)
except ValueError:
if any(every in pss for every in list(string.printable)) == False:
print('Password contains invalid characters')
Main.__init__()
if any(punct in pss for punct in list(string.punctuation)):
pass_type = 'alphasp'
Guesser.Guesser.check(pss, pass_type)
else:
pass_type = 'alpha'
Guesser.Guesser.check(pss, pass_type)
else:
pass_dict = dict()
for x in range(0, len(pss)):
try:
int(pss[x])
pass_dict[pss[x]] = 'num'
except ValueError:
if any(every in pss[x] for every in list(string.printable)) == False:
print('Password contains invalid characters')
Main.__init__()
if any(punct in pss[x] for punct in list(string.punctuation)):
pass_dict[pss[x]] = 'alphasp'
else:
pass_dict[pss[x]] = 'alpha'
pss = pass_dict
pass_type = None
Guesser.Guesser.check(pss, pass_type)
if __name__ == '__main__':
print('Your password(s) has to be 4 digits or longer and 15 digits or shorter; no spaces')
Main.__init__()


GUESSER.PY

import main
import time
import string
class Guesser():
#fixed
def check(pss, pass_type):
if pass_type != None:
if pass_type == 'num':
guess_param = 'n'
elif pass_type == 'alpha':
guess_param = 'a'
else:
guess_param = 'asp'
Guesser.guess(pss, guess_param)
else:
guess_param = None
Guesser.guess(pss, guess_param)
#working on this
def guess(pss, guess_param):
t1 = time.time()
tries = 0
#single passwords
if guess_param != None:
#numeric passwords
if guess_param == 'n':
gd = 0
zeroes = 3
gp = 0
while gp != pss:
gp = ('0' * zeroes) + str(gd)
tries = tries + 1
len1 = len(str(gd))
#adds to the guess digit to cycle through possibilities
gd = gd + 1
len2 = len(str(gd))
if gd > (10 ** len(gp)):
zeroes = zeroes + 1
gd = 0
if len2 > len1:
zeroes = zeroes - 1
#alphanumeric
####PROBLEM AREA###
elif guess_param == 'a':
letters = list(string.digits) + list(string.ascii_letters)
ll = len(letters) - 1
x = -1
gd = [letters[x]]
gdl = 1
xpos = 0
gp = 0
while gp != pss:
xpos = len(gd) - 1
if x + 1 <= 61:
x = x + 1
if xpos == 0:
gd = [x]
else:
gd[xpos] = x
else:
gdl = gdl + 1
x = -1
xpos = len(gd) - 1
gd.insert(0, 0)
for n in range(1, (len(gd) - 1)):
try:
gd[xpos - n] = gd[xpos - n] + 1
break
except gd[xpos - n] + 1 > ll:
gd[xpos - n] = 0
gp = gd
for n in range(0, (len(gp) - 1)):
for item in gp:
gp[n] = letters[item]
gp = ''.join(str(e) for e in gp)
print(gp)
###PROBLEM AREA ABOVE###
#for multiple passwords
else:
#for n in range(0, (len(pass_dict) - 1)):
pass
t2 = time.time()
t = t2 - t1
#simplifying the time it took; not really necessary but whatever
if t/60 > 1:
t = t/60
unit = 'minutes'
elif t/3600 > 1:
t = t/3600
unit = 'hours'
else:
unit = 'seconds'
print('Password guessed! Password was %s\nIt took %s %s and %s tries.' % (gp, t, unit, tries))

AJK AJK
Answer

Seems like you're trying to create your own logic to create all permutations of alpha numerics. BUT WHY !

Python can do trivial stuff like that on it's own, very easily.

import string
num = string.digits
alphanum = string.digits + string.ascii_lowercase

Now to get all possible digits for 3 digit numbers:

for i in itertools.product(num, num, num):
     print("".join(i))

To do this in a generic way, use the list multiplication operator. This example finds all permutations with 5 digits:

for i in itertools.product(*[num] * 5):
     print("".join(i))

You can loop over this to do 1-6 letter passwords.

Hence, by natural extension, alphanum is just:

for i in itertools.product(*[alphanum] * 5):
     print("".join(i))