Here's a password generator I created.
### THIS PROGRAM WAS CREATED FOR LEARNING PURPOSES ###
### AND SHOULD NOT BE USED TO CREATE PASSWORDS! ###
import string
from enum import Enum
from random import randint, shuffle, choice
class PasswordError(Exception):
__module__ = Exception.__module__
# Types of characters possible
class Types(Enum):
CAP = 'CAP' # Capital
SMA = 'SMA' # Small
DIG = 'DIG' # Digits
SPE = 'SPE' # Special
# Characters for each type of possible characters
type_chars = {
Types.CAP: string.ascii_uppercase,
Types.SMA: string.ascii_lowercase,
Types.DIG: string.digits,
Types.SPE: '!()-.?[]_`~;:@#$%^&*='
}
def password_generator(min_length=6, max_length=20, caps=1, small=1, digits=1, special=1):
types = {
Types.CAP: caps,
Types.SMA: small,
Types.DIG: digits,
Types.SPE: special,
}
num_chars = sum(list(types.values())) # Number of mandatory characters
min_length = max(num_chars, min_length) # In case 'num_chars' is greater
# Number of characters required for each possible type of character
# Is greater than maximum possible length
if min_length > max_length:
raise PasswordError(f'No password with the given criteria')
length = randint(min_length, max_length)
# List that stores the "types" of possible character
char_list = []
# Mandatory requirements
for typ, val in zip(types.keys(), types.values()):
char_list.extend([typ] * val)
# The remaining values to fill
for rem in range(length - num_chars):
char_list.append(choice(list(types.keys())))
shuffle(char_list)
password = ''
for typ in char_list:
password += choice(type_chars[typ])
return password
if __name__ == '__main__':
min_length = int(input('Minimum number of characters required: '))
max_length = int(input('Maximum number of characters possible: '))
print()
caps = int(input('Number of capital letters required: '))
small = int(input('Number of small letters required: '))
digits = int(input('Number of digits required: '))
special = int(input('Number of special characters required: '))
print()
number = int(input('Number of passwords required: '))
print('\n' + '-' * 50 + '\n')
print(' Here are your passwords: \n')
for i in range(number):
print(password_generator(min_length, max_length, caps, small, digits, special))
You can also modify the mandatory types of characters (Like 3 caps, 2 digits, etc). Also, minimum length and maximum length can be specified.
I think this code looks a bit ugly. How do I improve this?
password
intoPassword123!
instead, which add exactly zero security. \$\endgroup\$password
and 'medium' forPassword123!
and 'strong' forP@ssword$123!
\$\endgroup\$secrets
module for cryptographic-quality random numbers. \$\endgroup\$