Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 151 additions & 120 deletions passgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,141 +2,172 @@
# Author: Mohamed
# Description: A password generator

from time import time


def is_integer(input_string):
integer_list = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
for char in input_string:
if char not in integer_list:
return False
return True


def is_date(input_string):
if len(input_string) != 10:
return False

if input_string.count('-') != 2:
return False

if not is_integer(input_string.replace('-', '')):
return False

return True


def cases(input_string):
return [input_string.lower(), input_string.title(), input_string.upper()]


class PassGen:

def __init__(self):
self.pet = None
self.child = None
self.spouse = None
self.target = None
self.passwords = []

def prompt(self, txt):
return str(input(txt))
self.keywords_words = []
self.keywords_words_cases = []
self.keywords_integers = []
self.keywords_dates = []
self.passwords = set()

# generate all possible combinations using a list of cases
def chain_cases(self, case_list, i=0, input_combination=''):
for case in case_list[i]:
combination = input_combination + case
if len(case_list) == (i + 1):
self.keywords_words_cases.append(combination)
else:
self.chain_cases(case_list, i=i + 1, input_combination=combination)

def collect_keywords(self):

print('\n'
' Please enter keywords associated with the target, e.g. names, numbers, dates (like birthdays);\n'
' Dates have to have the following format: mm-dd-yyyy;\n'
' After entering all your keywords, press CTRL + C to generate the password list;\n')

# collect and categorize keywords
while True:
try:
keyword = input(' > ')

def question(self, target):
answers = {}
if len(keyword.replace(' ', '')) == 0:
pass

answers['firstname'] = self.prompt('Enter {}\'s first name: '.format(target))
answers['lastname'] = self.prompt('Enter {}\'s last name: '.format(target))
answers['nickname'] = self.prompt('Enter {}\'s nick name: '.format(target))
elif is_integer(keyword):
self.keywords_integers.append(keyword)

while True:
bday = self.prompt('Enter {}\'s birthday (mm-dd-yyyy): '.format(target))
elif is_date(keyword):
self.keywords_dates.append(keyword)

if not len(bday.strip()):
else:
self.keywords_words.append(keyword)

except KeyboardInterrupt:
print('\n')
break

if len(bday.split('-')) != 3:
print('Invalid birthday format\n')
continue

for _ in bday.split('-'):
if not _.isdigit():
print('Birthday only requires numbers\n')
continue

mm, dd, yyyy = bday.split('-')

if int(mm) > 12 or int(dd) > 31 or len(yyyy) != 4:
print('Invalid birthday\n')
continue

bday = { 'month': int(mm), 'day': int(dd), 'year': int(yyyy) }
break

answers['birthday'] = bday
return answers

def cases(self, word):
return [word.lower(), word.title()]

def fullname(self, fname, lname):
return ['{}{}'.format(a, b) for a in self.cases(fname) for b in self.cases(lname)]

def format_names(self):
for _ in range(1000):

iters = 0
for data in [self.target, self.spouse, self.child, self.pet]:

for n in ['firstname', 'lastname', 'nickname']:

fullname_list = []
name = data[n].strip()

if not len(name):
continue

if not iters:
fullname_list = self.fullname(data['firstname'], data['lastname'])
iters += 1

for word in self.cases(name) + fullname_list:

a, b, c = ('{}{}'.format(word, _),
'{}{}'.format(_, word),
'{0}{1}{0}'.format(_, word)
)

if not word in self.passwords:
self.passwords.append(word)

if not a in self.passwords:
self.passwords.append(a)

if not b in self.passwords:
self.passwords.append(b)

if not c in self.passwords:
self.passwords.append(c)

bday = data['birthday']

if bday:
d, e, f, g = (
'{}{}'.format(word, bday['year']),
'{}{}'.format(bday['year'], word),
'{}{}{}{}'.format(word, bday['month'], bday['day'], bday['year']),
'{}{}{}{}'.format(word, bday['day'], bday['month'], bday['year'])
)

if not d in self.passwords:
self.passwords.append(d)

if not e in self.passwords:
self.passwords.append(e)

if not f in self.passwords:
self.passwords.append(f)

if not g in self.passwords:
self.passwords.append(g)

def generator(self):
self.target = self.question('target')
print('\n')
def combine_words(self):

# add integers in reverse
for i in range(len(self.keywords_integers)):
self.keywords_integers.append(self.keywords_integers[i][::-1])

# generate all possible case combinations for word and it's parts
for word in self.keywords_words:
self.keywords_words_cases.append(word) # add word
self.keywords_words_cases.append(word[::-1]) # add word in reverse
cases_list = []

if ' ' in word:
word_parts = word.split(' ')
self.keywords_words_cases.append(''.join(word_parts)[::-1]) # add word without spaces in reverse

for part in word_parts:
self.keywords_words_cases.append(part)
self.keywords_words_cases.append(part[::-1])
part_cases = cases(part)
cases_list.append(part_cases)

else:
word_cases = cases(word)
cases_list.append(word_cases)

self.chain_cases(cases_list)

# add each custom integer as possible password
for i in self.keywords_integers:
self.passwords.add(i)

# generate passwords using all the parts and case combinations
for word in self.keywords_words_cases:

# add each word/part/case-combination as password
self.passwords.add(word)

# passwords with integers 0-2100 around it
word_number_combinations = []
for i in range(2100):
word_number_combinations += [
'{}{}'.format(word, i),
'{}{}'.format(i, word),
'{0}{1}{0}'.format(i, word)
]

# passwords with custom integers around it
word_custom_number_combinations = []
for i in self.keywords_integers:
word_custom_number_combinations += [
'{}{}'.format(word, i),
'{}{}'.format(i, word),
'{0}{1}{0}'.format(i, word)
]

for combination in (word_number_combinations + word_custom_number_combinations):
self.passwords.add(combination)

# passwords with date combinations in them
for date in self.keywords_dates:
date_parts = date.split('-')
data_month = date_parts[0]
date_day = date_parts[1]
date_year = date_parts[2]

word_date_combinations = [
'{}{}'.format(word, date_year),
'{}{}'.format(date_year, word),
'{}{}{}{}'.format(word, date_day, data_month, date_year),
'{}{}{}{}'.format(word, data_month, date_day, date_year),
'{}{}{}{}'.format(word, date_year, data_month, date_day)
]

for combination in word_date_combinations:
self.passwords.add(combination)

self.spouse = self.question('spouse')
print('\n')
def generator(self):
self.collect_keywords()
self.combine_words()

self.child = self.question('child')
print('\n')
password_file_name = 'passwords_' + str(round(time())) + '.txt'
print(' Passwords Generated: {}'.format(len(self.passwords)))

self.pet = self.question('pet')
print('\n')

self.format_names()
with open(password_file_name, 'w+') as password_file:
for password in sorted(self.passwords):
password_file.write(password + '\n')

output_file = '{}.txt'.format(self.target['firstname'].lower()
if self.target['firstname'] else 'pass.txt')

with open(output_file, 'wt') as f:
for pwd in self.passwords:
f.write('{}\n'.format(pwd))
print(' Passwords written to {}'. format(password_file_name))
input(' Press any key to exit ...')

print('Passwords Generated: {}'. format(len(self.passwords)))

if __name__ == '__main__':
PassGen().generator()
PassGen().generator()