Build a Password Generator in Python
Code a strong, random password generator in Python. Choose a length, mix letters, digits and symbols, and build the password with random.choice in a loop. Full runnable code, security tips and a quiz.
Key takeaways
- The string module gives ready-made sets of letters, digits and punctuation
- Building a pool of allowed characters lets you control the password's strength
- A loop with random.choice picks one character at a time to build the password
- Longer passwords with mixed character types are far harder to crack
- For real security, the secrets module is preferred over random
Make a password no one can guess
Weak passwords like password123 are cracked in seconds. Strong ones are long and random, mixing upper- and lower-case letters, digits and symbols. Typing such a password by hand is hard — so let's make Python do it. This project builds a generator that produces a fresh, strong password every run.
It builds on ideas from working with text and strings and pairs well with our lesson on cybersecurity and strong passwords.
Step 1: gather the characters
We don't want to type out the whole alphabet. Python's built-in string module already has these collections ready:
import string
print(string.ascii_letters) # abc...xyzABC...XYZ
print(string.digits) # 0123456789
print(string.punctuation) # !"#$%&'()*+,-./:;<=>?@[...]
ascii_letters is every letter, digits is 0–9, and punctuation is the symbols. We'll combine the ones we want into a single pool of allowed characters.
Step 2: build the pool
import string
pool = string.ascii_letters + string.digits + string.punctuation
Joining the three strings with + gives one long string holding every character the password may contain. A bigger pool means a stronger password.
Step 3: pick characters in a loop
To build a password of a chosen length, we pick one random character at a time and join it on:
import random
import string
pool = string.ascii_letters + string.digits + string.punctuation
length = 12
password = ""
for i in range(length):
password += random.choice(pool)
print(password)
random.choice(pool) grabs one character; password += ... appends it. After 12 turns we have a 12-character password. (For more on the loop, see python for loops.)
The complete generator
Here's the finished program. It asks the player which character types to include and how long the password should be, then generates it:
import random
import string
def make_password(length, use_letters, use_digits, use_symbols):
pool = ""
if use_letters:
pool += string.ascii_letters
if use_digits:
pool += string.digits
if use_symbols:
pool += string.punctuation
if pool == "":
return "ERROR: choose at least one character type."
password = ""
for i in range(length):
password += random.choice(pool)
return password
print("=== PASSWORD GENERATOR ===")
while True:
length = int(input("How long? (e.g. 12): "))
letters = input("Include letters? (yes/no): ").lower() == "yes"
digits = input("Include digits? (yes/no): ").lower() == "yes"
symbols = input("Include symbols? (yes/no): ").lower() == "yes"
result = make_password(length, letters, digits, symbols)
print("Your password:", result)
again = input("Generate another? (yes/no): ").lower()
if again != "yes":
print("Stay safe online!")
break
How it works:
make_passwordbuilds the pool from only the character types the user wants. Eachifadds a chunk to the pool.- If nothing is chosen, the pool is empty, so we return a friendly error instead of crashing.
- The
forloop pickslengthrandom characters and joins them into the password. - The comparison
input(...).lower() == "yes"turns the answer straight intoTrueorFalse.
A sample run:
=== PASSWORD GENERATOR ===
How long? (e.g. 12): 14
Include letters? (yes/no): yes
Include digits? (yes/no): yes
Include symbols? (yes/no): yes
Your password: 7p$Qk2!mZ9rB#x
Generate another? (yes/no): no
Stay safe online!
Make it genuinely secure
The random module is great for games but is predictable to a determined attacker. For passwords you actually use, swap in the secrets module — it works almost identically but uses cryptographically secure randomness:
import secrets
import string
pool = string.ascii_letters + string.digits + string.punctuation
password = "".join(secrets.choice(pool) for _ in range(16))
print(password)
Just import secrets and call secrets.choice instead of random.choice. That one change makes your generator safe for real-world use.
Try it yourself
Level up your generator:
- Guarantee a mix. Force at least one digit and one symbol so the password is never all letters. After building it, check it contains each required type and regenerate if not.
- Rate the strength. Print "Weak", "Medium" or "Strong" based on the length and how many character types were used.
- Memorable mode. Instead of random characters, join three or four random words from a list with hyphens, like
river-camel-sky-42. Long word passwords are strong and easy to remember. - Save to a file. Append each generated password to a file so you don't lose it. See reading and writing files in Python.
Quick quiz
Test yourself and earn XP
What does string.ascii_letters contain?
string.ascii_letters is 'abc...xyzABC...XYZ' — every lower and upper case letter.
How do we add one random character to the password?
random.choice(pool) picks one character and += joins it onto the growing password string.
Which password is hardest to crack?
A long mix of upper, lower, digits and symbols has the most combinations and no dictionary words.
Why might you use the secrets module instead of random?
secrets is designed for security-sensitive randomness like passwords and tokens; random is fine for games but not secrets.
How does a longer password help?
More characters means exponentially more combinations, so guessing becomes far slower.
FAQ
For learning and casual use it's fine, but Python's random module is predictable to an attacker who knows enough. For passwords you actually rely on, use the secrets module: secrets.choice(pool) works the same way but uses your operating system's cryptographically secure randomness. The code change is tiny and the security gain is large.
Each character type you allow makes the 'pool' bigger, so each position in the password has more possibilities. A 12-character password drawn from ~90 possible characters has astronomically many combinations, which is what stops attackers guessing it. Length matters most, but variety helps too. Learn more in our lesson on cybersecurity and strong passwords.
Keep exploring
More in Coding