A CLI tool that generates cryptographically secure passwords of any length, checks the strength of any password you type, and explains exactly what makes it weak or strong.
Use the secrets module — not random — for cryptographically secure passwords. The secrets module is specifically designed for generating tokens and passwords.
import secrets
import string
def generate_password(length=16, use_upper=True, use_digits=True, use_symbols=True):
chars = string.ascii_lowercase
if use_upper: chars += string.ascii_uppercase
if use_digits: chars += string.digits
if use_symbols: chars += string.punctuation
# secrets.choice is cryptographically secure (unlike random.choice)
password = ''.join(secrets.choice(chars) for _ in range(length))
return password
# Generate a few
for _ in range(5):
print(generate_password(16))
mK9#vLpX2@nRqT8w Yz7$bNsQ4&hJcW3e aP5!dFxM1*kUiG6r Bj8^oEtH3%lVnC0y wR2@sIpA9#mZqD7f
Score the password on five criteria: length, uppercase, lowercase, digits, and symbols.
import re
def check_strength(password):
score = 0
feedback = []
checks = [
(len(password) >= 8, '+1 Length >= 8 characters'),
(len(password) >= 14, '+1 Length >= 14 characters (bonus)'),
(bool(re.search(r'[A-Z]', password)), '+1 Contains uppercase letters'),
(bool(re.search(r'[a-z]', password)), '+1 Contains lowercase letters'),
(bool(re.search(r'\d', password)), '+1 Contains numbers'),
(bool(re.search(r'[^A-Za-z0-9]', password)), '+1 Contains symbols'),
]
for passed, message in checks:
if passed:
score += 1
feedback.append(f' ✅ {message}')
else:
feedback.append(f' ❌ {message}')
labels = {6: 'VERY STRONG', 5: 'STRONG', 4: 'GOOD', 3: 'FAIR', 2: 'WEAK', 1: 'VERY WEAK', 0: 'TERRIBLE'}
bars = {6: '██████', 5: '█████░', 4: '████░░', 3: '███░░░', 2: '██░░░░', 1: '█░░░░░', 0: '░░░░░░'}
return score, labels.get(score, 'WEAK'), bars.get(score, '░░░░░░'), feedback
score, label, bar, tips = check_strength("hello123")
print(f'Strength: {bar} {label} ({score}/6)\n')
for tip in tips:
print(tip)
Strength: ███░░░ FAIR (3/6) ✅ +1 Length >= 8 characters ❌ +1 Length >= 14 characters (bonus) ❌ +1 Contains uppercase letters ✅ +1 Contains lowercase letters ✅ +1 Contains numbers ❌ +1 Contains symbols
Combine generator and checker into a menu-driven command-line app.
def main():
print("=" * 45)
print(" 🔐 Password Tool")
print("=" * 45)
while True:
print("\n1. Generate a password")
print("2. Check password strength")
print("3. Exit")
choice = input("\nChoice: ").strip()
if choice == '1':
try:
length = int(input("Length (default 16): ").strip() or 16)
except ValueError:
length = 16
use_symbols = input("Include symbols? (y/n, default y): ").lower() != 'n'
pwd = generate_password(length, use_symbols=use_symbols)
print(f"\nGenerated: {pwd}")
score, label, bar, tips = check_strength(pwd)
print(f"Strength: {bar} {label} ({score}/6)")
elif choice == '2':
pwd = input("Enter password to check: ")
score, label, bar, tips = check_strength(pwd)
print(f"\nStrength: {bar} {label} ({score}/6)\n")
for tip in tips:
print(tip)
elif choice == '3':
print("Goodbye!")
break
if __name__ == '__main__':
main()
============================================= 🔐 Password Tool ============================================= 1. Generate a password 2. Check password strength 3. Exit Choice: 1 Length (default 16): 20 Include symbols? (y/n, default y): y Generated: mK9#vLpX2@nRqT8w!eBz Strength: ██████ VERY STRONG (6/6)
Your tool uses secrets — Python's cryptographically secure module backed by the OS random source — which means the passwords are genuinely unpredictable. The strength checker logic is the same approach used by HaveIBeenPwned and major password managers.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.