-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
85 lines (65 loc) · 2.08 KB
/
main.py
File metadata and controls
85 lines (65 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import argparse
import secrets
import string
DEFAULT_LENGTH = 16
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Generate secure passwords from the terminal."
)
parser.add_argument(
"--length",
type=int,
default=DEFAULT_LENGTH,
help="Number of characters in each password.",
)
parser.add_argument(
"--count",
type=int,
default=1,
help="How many passwords to generate.",
)
parser.add_argument(
"--no-symbols",
action="store_true",
help="Skip special characters and use only letters and numbers.",
)
return parser.parse_args()
def build_charset(include_symbols: bool) -> str:
charset = string.ascii_letters + string.digits
if include_symbols:
charset += "!@#$%^&*()-_=+[]{}"
return charset
def generate_password(length: int, include_symbols: bool) -> str:
if length < 8:
raise ValueError("Password length must be at least 8 characters.")
pools = [
string.ascii_lowercase,
string.ascii_uppercase,
string.digits,
]
if include_symbols:
pools.append("!@#$%^&*()-_=+[]{}")
if length < len(pools):
raise ValueError("Length is too short for the selected password rules.")
password_chars = [secrets.choice(pool) for pool in pools]
charset = build_charset(include_symbols)
while len(password_chars) < length:
password_chars.append(secrets.choice(charset))
secrets.SystemRandom().shuffle(password_chars)
return "".join(password_chars)
def main() -> None:
args = parse_args()
try:
passwords = [
generate_password(args.length, not args.no_symbols)
for _ in range(max(1, args.count))
]
except ValueError as error:
print(f"Error: {error}")
raise SystemExit(1) from error
print("\nGenerated passwords")
print("-------------------")
for index, password in enumerate(passwords, start=1):
print(f"{index}. {password}")
if __name__ == "__main__":
main()