I made a password generator which takes one strings, and alters the character to the leet character.
It also check if the password is complicated enough to meet some of the criteria(eg. length, uppercase, lowercase, symbol), as well as it checks if the generated password has been seen in the past data breach.
Output example
shogokobayashi 100p $ python3 password_generator.py iamsleepy Password generated: i@MSL3EpY Password is complex enough: True Generated password is not found in the previous pwned database.
import hashlib import random import re import sys import requests def generate_password(source_str): """ Generate password candidate from the given strings by altering some characters with leet Input: A String Return: A Password candidate string """ if not any(character.isupper() for character in source_str): temp_str = "" for char in source_str: if random.choice([True, False]): char = char.upper() temp_str += char source_str = temp_str leet_dict = { "a": ["@", "4", "^", "a"], "b": ["8", "b"], "c": ["[","<","(", "c"], "d": [")", "d"], "e": ["3","&", "e"], "f": ["f"], "g": ["6", "[", "(", "g"], "h": ["#", "h"], "i": ["1", "!", "i"], "j": ["j"], "k": ["k"], "l": ["1", "l"], "m": ["m"], "n": ["n"], "o": ["0", "o"], "p": ["p"], "q": ["q"], "r": ["2", "r"], "s": ["5", "$", "s"], "t": ["+", "7", "t"], "u": ["u"], "v": ["v"], "w": ["w"], "x": ["x"], "y": ["y"], "z": ["z"], } candidate = "" for c in source_str: if leet_dict.get(c): c = random.choice(leet_dict[c]) candidate += c return candidate def is_password_complicated(password): """ Reference from stackoverflow: https://stackoverflow.com/questions/16709638/checking-the-strength-of-a-password-how-to-check-conditions Verify the strength of 'password' Returns a dict indicating the wrong criteria A password is considered strong if: 8 characters length or more 1 digit or more 1 symbol or more 1 uppercase letter or more 1 lowercase letter or more Return: Boolean """ # calculating the length has_length = len(password) >= 8 # searching for digits has_digit = re.search(r"\d", password) is not None # searching for uppercase has_uppercase = re.search(r"[A-Z]", password) is not None # searching for lowercase has_lowercase = re.search(r"[a-z]", password) is not None # searching for symbols has_symbol = re.search(r"\W", password) is not None # overall result return (has_length and has_digit and has_uppercase and has_lowercase and has_symbol) def is_pwned(candidate): """ Check "Have I been pwned" to see if the generated password was seen in the previous data breach :param candidate: generated password :return: Boolean """ m = hashlib.sha1(candidate.encode('utf-8')) url = "https://api.pwnedpasswords.com/pwnedpassword/" + m.hexdigest() response = requests.get(url) if response.status_code == 200: return True elif response.status_code == 404: return False else: raise Exception if __name__ == '__main__': if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} source_string") sys.exit(1) elif len(sys.argv[1]) < 8: print("Provided string is too short. Please provide at least 8 characters strings for optimum result.") sys.exit(1) generated_password = generate_password(sys.argv[1]) print(f"Password generated: {generated_password}") complexity_result = is_password_complicated(generated_password) print(f"Password is complex enough: {complexity_result}") pwned = is_pwned(generated_password) if pwned: print("Generated password is found in the pwned database, you may want to run this script again to generate another password..." ) else: print("Generated password is not found in the previous pwned database.")