# Password generator + storage console app

This is my code to generate and store password localy hashed in txt file. I would like to kindly ask you whether you could review my code. Btw it is coded as console app. I am currently working on making GUI. Thanks in advance.

import random
import hashlib

class randomPass():
action = ''
def __init__(self):
# SETUP
self.passdic = {}

self.num_lines = sum(1 for line in open('passwords.txt'))
for i in range(self.num_lines):
self.content = list(self.content.split())
self.passdic[self.content[0]] = self.content[1]

self.leng = 14
self.action = ''
self.gPass = ''
# work as i want to
self.myPass = ''

print('perform one of the actions')
while self.action != 'break':
self.action = input()
if self.action == 'generate':
self.leng = int(input())
print('generated')
elif self.action == 'save':
self.savePass(self.gPass)
else:
print(self.action + 'is not a valid action')

znaky = ['"', "'", '!', '#', '\$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[',
']', '^', '_', '', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~']

pword = ''.join([znaky[random.randint(0, len(znaky) - 1)] for i in range(lengthOfPassword)])
return pword

self.myPass = hashlib.md5((input().encode('utf-8'))).hexdigest()
if self.myPass in self.passdic:
else:

af.write(self.myPass + ' ' + generatedPassword + '\n')

self.myPass = hashlib.md5((input().encode('utf-8'))).hexdigest()
if self.myPass in self.passdic:
print(self.passdic[self.myPass])
else:

a = randomPass()
print('fin')


There is no particular need for this to be a class. While the reading of the file and the writing of the file are coupled, IMO this is not yet enough to make it into a class.

What is especially confusing is that you use members even for local variables which are not needed in the other methods.

def read_password_file(file_name="passwords.txt"):
with open(file_name) as f:


This also allows using a different file than the default. It uses a dictionary comprehension and the fact that files are iterable.

The generation of the random passwords should be separate from the CLI interface (in case you want to change one without the other). The generation itself can also be simplified by using the string module:

import random
from string import ascii_lowercase, ascii_uppercase, digits, punctuation

ALLOWED_CHARS = ascii_lowercase + ascii_uppercase + digits + punctuation

def generate_random_pass_word(length=14, allowed_chars=ALLOWED_CHARS):
return "".join(random.choices(allowed_chars, k=length))


This uses the random.choices function introduced in Python 3.6.

import hashlib

def get_key(name):
return hashlib.md5(name.encode('utf-8')).hexdigest()

return
print('to save the generated pass word give it a name')
name = get_key(input())
else:
with open(file_name, 'a') as f:

print('to read the generated pass word type its name')
name = get_key(input())
else:


Note that I call your self.myPass what it is, a simple name. It is not really a password (you could look it up in the file and use a rainbow table to get the cleartext) and even the context of having to think of a good password to store your good password seems ridiculous (do you use this password generation function to generate this password? What password do you use to store that password?).

I also used the new f-string (Python 3.6+) to simplify the writing to the file.

And finally, your main function, which has the user interface:

def main():
pass, action = None, None

print('perform one of the actions')
while action != 'break':
if action == 'generate':
length = int(input())
pass = generate_random_pass_word(length)
print('generated:', pass)
elif action == 'save':
else:
print(action + 'is not a valid action')

if __name__ == "__main__":
main()
print('fin')


Note that I put the calling of main under a if __name__ == "__main__":` guard to allow importing from this script from another script.

• Thank you! I am planning to rewrite this to a simple GUI with tkinter module. Do you recommen me to put GUI and password generation in separate class? Btw the point behind this is only having to remember your simple password such as your name and you can use it to protect even the most private things. Nov 28 '18 at 17:41
• @MatejNovosad Yes, I would put the GUI, the CLI and the password generation in different functions/classes. Nov 28 '18 at 18:17
• @MatejNovosad Well, if your name is your password, then now you have a weak password protecting your strong password, so now the only difference from having a weak password in the first place is some security by obscurity and the weak password being under your control (instead of on someone else's server). You are probably better of in having something like a password vault, which is protected by a single strong password, instead of each password being protected by its own potentially weak password. Nov 28 '18 at 18:20
• @MatejNovosad In addition, your logic is slightly wrong in another place. If I manage to read that file, I know all your passwords. They are saved in cleartext. I don't know for which site, but I know that they are passwords you use somewhere. You usually want to encrypt that part, not the identifier. Nov 28 '18 at 18:27
• truth is when you manage to get to that file you can use generated passwords you have found in dictionary attack. Nov 28 '18 at 18:41