Skip to content

Instantly share code, notes, and snippets.

@AberrantWolf
Last active October 16, 2019 11:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AberrantWolf/86b0431b76024b07e70ff61017a51033 to your computer and use it in GitHub Desktop.
Save AberrantWolf/86b0431b76024b07e70ff61017a51033 to your computer and use it in GitHub Desktop.
Generate random passwords that meet some criteria
import random
import string
NUM_CHARS = 7
# pick types are "random", "first", and "last"
PICK_TYPE = "last"
# options are "allowed", "required", and "none"
UPPER_CASE = "required"
LOWER_CASE = "required"
NUMBER = "required"
SYMBOL = "required"
# VALID_SYMBOLS = "!@#$%^&*()_+-="
ALLOWED_TYPES = []
def init_valid_types():
if LOWER_CASE is not "none":
ALLOWED_TYPES.append("lower")
if UPPER_CASE is not "none":
ALLOWED_TYPES.append("upper")
if NUMBER is not "none":
ALLOWED_TYPES.append("number")
if SYMBOL is not "none":
ALLOWED_TYPES.append("symbol")
class PasswordCharMeta:
def __init__(self):
self.selected_type = pick_value(ALLOWED_TYPES)
self.is_protected = False
def pick_value(options):
if PICK_TYPE is "random":
return random.choice(options)
elif PICK_TYPE is "first":
return options[0]
elif PICK_TYPE is "last":
idx = len(options) - 1
return options[idx]
else:
print("ERROR: invalid pick type specified (" + PICK_TYPE + ")")
return None
def get_char(kind = "any"):
if kind is "lower":
return pick_value(string.ascii_lowercase)
elif kind is "upper":
return pick_value(string.ascii_uppercase)
elif kind is "number":
return pick_value(string.digits)
elif kind is "symbol":
return pick_value(string.punctuation)
else:
return "[INVALID TYPE: " + kind + "]"
def get_unprotected_indices(passwordMetas):
indices = []
for i, m in enumerate(passwordMetas):
if not m.is_protected:
indices.append(i)
return indices
def enforce_category_helper(passwordMetas, category_name, category_class):
if category_class is "required":
category_idxs = []
for i, m in enumerate(passwordMetas):
if m.selected_type is category_name:
category_idxs.append(i)
if len(category_idxs) < 1:
print("Forcing category: " + category_name)
valid_indices = get_unprotected_indices(passwordMetas)
if len(valid_indices) < 1:
print("ERROR: No valid available slots for required category " + category_name)
return
rand_idx = pick_value(valid_indices)
passwordMetas[rand_idx].selected_type = category_name
category_idxs.append(rand_idx)
passwordMetas[pick_value(category_idxs)].is_protected = True
def enforce_required_categories(passwordMetas):
enforce_category_helper(passwordMetas, "upper", UPPER_CASE)
enforce_category_helper(passwordMetas, "lower", LOWER_CASE)
enforce_category_helper(passwordMetas, "number", NUMBER)
enforce_category_helper(passwordMetas, "symbol", SYMBOL)
def gen_password():
passwordMetas = list()
for _ in range(0, NUM_CHARS):
passwordMetas.append(PasswordCharMeta())
enforce_required_categories(passwordMetas)
password = ""
for ch in passwordMetas:
password = password + get_char(ch.selected_type)
return password
if __name__ == "__main__":
init_valid_types()
print("Your password is: " + gen_password())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment