forked from Grow-with-Open-Source/Python-Projects
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpassword.py
More file actions
135 lines (109 loc) · 4.07 KB
/
password.py
File metadata and controls
135 lines (109 loc) · 4.07 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import random
import string
def main():
option = ""
while option not in ("1", "2"):
option = input(
"What would you like to do:\n"
"1 Generate a secure password\n"
"2 Check the strength of my password\n> "
)
if option not in ("1", "2"):
print("Please choose 1 or 2.")
if option == "1":
choice = None
length = None
while choice not in (1, 2, 3, 4):
try:
choice = int(
input(
"Choose password type:\n"
"1 Mix of numbers, letters and symbols (Recommended)\n"
"2 Numbers only password\n"
"3 Letters only password\n"
"4 Symbols only password\n> "
)
)
if choice not in (1, 2, 3, 4):
print("Invalid choice, try again.")
except ValueError:
print("Invalid input, enter numbers only.")
while length not in range(4, 21):
try:
length = int(input("Enter your desired length (between 4 and 20): "))
if length not in range(4, 21):
print("Invalid length, try again.")
except ValueError:
print("Invalid input, enter numbers only.")
if choice == 1:
passwd = mix_of_all(length)
elif choice == 2:
passwd = generate_number_only(length)
elif choice == 3:
passwd = generate_letters_only(length)
else:
passwd = generate_symbols_only(length)
print("Here is your password:", passwd)
if input("Would you like a report for this password? (y/n): ").lower() == "y":
print(password_report(passwd))
else: # option == "2"
existing = input("Enter the password you want to check: ")
print(password_report(existing))
def generate_number_only(length):
digits = string.digits
return "".join(random.choice(digits) for _ in range(length))
def generate_letters_only(length):
letters = string.ascii_letters
return "".join(random.choice(letters) for _ in range(length))
def generate_symbols_only(length):
symbols = "!@#$%^&*()-_=+[]{};:,.<>?/\\|"
return "".join(random.choice(symbols) for _ in range(length))
def mix_of_all(length):
pool = string.ascii_letters + string.digits + "!@#$%^&*()-_=+[]{};:,.<>?/\\|"
return "".join(random.choice(pool) for _ in range(length))
def password_report(password: str) -> str:
recommended_length = 8
length = len(password)
upper = lower = digits = symbols = 0
for letter in password:
if letter.isupper():
upper += 1
elif letter.islower():
lower += 1
elif letter.isdigit():
digits += 1
else:
symbols += 1
parts = []
# Length report
diff = recommended_length - length
if diff > 0:
parts.append(
f"The password has a length of {length} characters, {diff} less than the recommended {recommended_length}."
)
else:
parts.append(
f"The password has a length of {length} characters, which meets or exceeds the recommended {recommended_length}."
)
# Composition report
parts.append(
f"It has {upper} uppercase letter(s), {lower} lowercase letter(s), {digits} number(s), and {symbols} symbol(s)."
)
suggestions = []
if upper == 0:
suggestions.append("add at least one uppercase letter")
if lower == 0:
suggestions.append("add at least one lowercase letter")
if digits == 0:
suggestions.append("add at least one number")
if symbols == 0:
suggestions.append("add a symbol for extra strength")
if suggestions:
parts.append(
"To improve this password, you could " + ", ".join(suggestions) + "."
)
else:
parts.append("This password has a good mix of character types.")
return " ".join(parts)
if __name__ == '__main__':
main()