-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproject.py
138 lines (106 loc) · 4.63 KB
/
project.py
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
136
137
138
# Import all relevant modules
# Always search for modules before working on a function
# Someone else may have done it before which will likely be better than your own implementation
import random
import string
import sqlite3
import os
def main():
# Take user input and ask the user to select the wordlist they want to use
while True:
print("\nHi, I will help you generate the password. First select the wordlist.")
print("\nThere are two wordlists available: \n\t1. avro_wordlist and 2. phonetic_wordlist")
print("\nEnter 1 or 2. All other inputs will be ignored and the app will reprompt.")
w = input("Input: ").strip()
if w == "1":
selected_list = "1_avro_wordlist.txt"
break
if w == "2":
selected_list = "2_phonetic_wordlist.txt"
break
# Get words and initialize password as an empty str
# The first parameter which is now set as 3 may be changed to get 4, 5 or more words
words = bn_words(3, selected_list)
password = ""
# Add random chars() separator to words to make the password strong
for i in words:
sep = chars()
word = i
password += word + sep
# Nicely formating the printed output
print(f"\n = = = = = = = = \nGENERATED PASSWORD\n = = = = = = = = \n")
print(f"{password}\n")
# Save the historical usage data of how many times a specific word is used in password generation
save(words)
def chars(length=3, alpha=False, special_chars=True):
# Get the characters from the string module
letters = string.ascii_uppercase
digits = string.digits
special = string.punctuation
# Remove less commonly used chars
# To ensure the pass is easier to memorize
remove_chars = "!\"',./:;\\^`|"
# Update special
special = ''.join(char for char in special if char not in remove_chars)
# Debug print the allowed chars
# print(letters, digits, special)
# Create the character list that are allowed in the password
allowed_chars = digits
if alpha:
allowed_chars += letters
if special_chars:
allowed_chars += special
# Use the allowed chars to generate a password while considering function parameters
pwd = ""
while len(pwd) < length:
rand_char = random.choice(allowed_chars)
pwd += rand_char
# Finally, return the password
return pwd
def bn_words(word_count=3, input_wordlist="1_avro_wordlist.txt"):
# Check the validity of word count argument
if not word_count:
raise ValueError("Missing parameter.")
# Check if the file exists
if not os.path.exists(input_wordlist):
raise FileNotFoundError(f"The wordlist file was not found.")
# IMPORTANT: This function chooses the words from the input_wordlist input file
# Make sure that all words are of at least 3 chars to ensure security of the generated passwords
with open(input_wordlist, 'r') as file:
# Read the words from the file into a list
words_list = [line.strip() for line in file]
# Check if there are at least 4 words in the list
if len(words_list) < 4:
raise ValueError("Insufficient words to generate a 4-word password.")
# Choose random words equal to word_count
selected_words = random.sample(words_list, word_count)
# Return the words
return selected_words
def save(words_to_save):
# Check for errors
if not words_to_save or len(words_to_save) < 1:
raise ValueError("No words returned.")
# IMPORTANT: Establish a connection to the SQLite database
c = sqlite3.connect('project.db')
cursor = c.cursor()
# Loop over the list of words
for word in words_to_save:
# Check if the word exists in the database
cursor.execute("SELECT word FROM words WHERE word = ?", (word,))
check_for_word = cursor.fetchone()
# If the word doesn't exist, create a new entry
if check_for_word is None:
cursor.execute("INSERT INTO words (word, times_used) VALUES (?, ?)", (word, 1))
else:
# If the word exists, update the times_used
existing_word = check_for_word[0] if check_for_word else None
if existing_word == word:
cursor.execute("UPDATE words SET times_used = times_used + 1 WHERE word = ?", (word,))
else:
# Handle the case where the fetched word is not equal to the expected word
raise Exception("Unexpected case: Fetched word is not equal to the expected word.")
# Commit the changes and close the connection
c.commit()
c.close()
if __name__ == "__main__":
main()