import secrets
import string
from typing import Optional
class PasswordGenerator:
def __init__(
self,
length: int = 16,
include_uppercase: bool = true,
include_lowercase: bool = true,
include_digits: bool = true,
include_special: bool = true,
exclude_ambiguous: bool = false
):
self.length = length
self.characters = self._build_character_set(
include_uppercase,
include_lowercase,
include_digits,
include_special,
exclude_ambiguous
)
def _build_character_set(
self,
include_uppercase: bool,
include_lowercase: bool,
include_digits: bool,
include_special: bool,
exclude_ambiguous: bool
) -> str:
chars = ""
if include_uppercase:
chars += string.ascii_uppercase
if include_lowercase:
chars += string.ascii_lowercase
if include_digits:
chars += string.digits
if include_special:
chars += string.punctuation
if exclude_ambiguous:
ambiguous = "0O1lI"
chars = "".join(c for c in chars if c not in ambiguous)
if not chars:
raise ValueError("At least one character set must be enabled")
return chars
def generate(self) -> str:
"""Generate a secure random password."""
return "".join(secrets.choice(self.characters) for _ in range(self.length))
def estimate_strength(self, password: str) -> str:
"""Estimate password strength."""
entropy = len(set(password)) * len(password)
if entropy < 30:
return "weak"
elif entropy < 60:
return "medium"
else:
return "strong"