Skip to content

Instantly share code, notes, and snippets.

@therightstuff
Last active February 19, 2021 12:47
Show Gist options
  • Save therightstuff/0384b4b1201a2679eee9f2fd49e69c9c to your computer and use it in GitHub Desktop.
Save therightstuff/0384b4b1201a2679eee9f2fd49e69c9c to your computer and use it in GitHub Desktop.
Generate a secure python password with no dependencies
"""
A simple password generator that produces secure passwords of a given length
without requiring the installation of additional modules.
The four valid password characters classes - lowercase, uppercase, digits and
punctuation - are inserted randomly into the password using cryptographically
strong random numbers from the secrets module until the password length
requirement is met, ensuring that each of the classes is included in the password.
Password strength verified with https://www.security.org/how-secure-is-my-password/
NOTE: I've put a lower limit of 8 characters, which is standard, but the very first
example this produced was "b`q8M1N/", which can apparently be cracked in about 12
hours. Longer passwords are better. See https://xkcd.com/936/
"""
import secrets
import string
def generate_password(desired_length):
# don't even bother with passwords shorter than 8 characters
if desired_length < 8:
raise Exception("Passwords should be 8 characters or more")
# randomly select at least enough characters from each character class
valid_char_classes = [
string.ascii_lowercase,
string.ascii_uppercase,
string.digits,
string.punctuation ]
# generate an array of password characters
password = []
# loop over the character classes until we've completed the password
while True:
for char_class in valid_char_classes:
# randomly select a character from the class
random_char = secrets.choice(char_class)
# randomly select the insert position
insert_position = secrets.randbelow(len(password) + 1)
# insert the character at that position
password.insert(insert_position, random_char)
# return the password string when complete
if len(password) == desired_length:
return "".join(password)
# choose a password length between 8 and 20
desired_length = 8 + secrets.randbelow(13)
print(f"Generated password of length {desired_length}: {generate_password(desired_length)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment