Password Generator & Strength Checker 🔐
Two tools in one: generate a genuinely strong password, and rate how weak an existing one is. It is a great excuse to internalise the difference between random and secrets, which is the difference between fun and safe.
📋 Build this
- Generate a password of a requested length from letters, digits and symbols.
- Use the secrets module, never random, for anything security-related.
- Rate a given password: length, character variety, obvious weaknesses.
- Give a clear verdict and one concrete suggestion.
Hints, if you want them
Try the spec cold first. Open a hint only when you are properly stuck; the struggle is where the learning is.
Hint 1: Generating safely
secrets.choice(alphabet) in a loop, or ''.join(secrets.choice(chars) for _ in range(length)). Never random: it is predictable (Lesson 52).Hint 2: Rating strength
Score by length and by how many character classes appear (lower, upper, digit, symbol). Use
any(c.isdigit() for c in pw) and friends.Hint 3: Honest feedback
A short password with one character class is weak no matter what. Say so plainly, and suggest the single most effective fix (usually: make it longer).
The reference solution
Yours does not need to match this. There are many good ways to build any of these. Compare only after you have your own working.
Reveal the reference solution
import secrets
import string
def generate(length=16):
"""Generate a strong password. secrets, not random (Lesson 52)."""
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
return "".join(secrets.choice(alphabet) for _ in range(length))
def rate(password):
"""Return a verdict and one suggestion."""
classes = sum([
any(c.islower() for c in password),
any(c.isupper() for c in password),
any(c.isdigit() for c in password),
any(c in "!@#$%^&*" for c in password),
])
if len(password) < 8 or classes < 2:
return "weak", "Make it at least 12 characters with mixed types."
if len(password) < 12 or classes < 3:
return "medium", "A little longer, and mix in more character types."
return "strong", "Good. Consider a password manager for the rest."
# generate() uses secrets, so its output changes each run; rate() is deterministic
for example in ["password", "P4ssw0rd", "correct-horse-battery-staple-9!"]:
verdict, tip = rate(example)
print(f"{verdict:7} {example}")
weak password
medium P4ssw0rd
strong correct-horse-battery-staple-9!Stretch goals
- Check a password against a list of the most common ones and reject matches.
- Generate a memorable passphrase from a word list instead of random characters.
- Never print or log the generated password anywhere it could leak (Lesson 52).