Home > database >  How to create a password generator without repeated passwords?
How to create a password generator without repeated passwords?

Time:02-27

I created a password generator but the problem is if I requested big number of passwords, some passwords are repeated. I'm trying to find a way to replace the repeated passwords by non-repeated ones, and I can't figure it out. Here's the code:

import random
import string
import os

chars = string.ascii_letters   string.digits   string.punctuation
number = int(input('Enter the number of passwords you want: '))
length = int(input('Enter the length of the passwords: '))
print('Do you want to save the output in a file?(Y, n) ')
answer = input()
if answer == 'Y':
    fname = input('Enter file name: ')   '.txt'
    current_path = os.getcwd()
    fpath = os.path.join(current_path, fname)
    lst = []
    for pwd in range(number):
        password = ''
        for c in range(length):
            password  = random.choice(chars)
        print(password)
        lst.append(password)
    with open(fpath, 'w') as file:
        for item in lst:
            file.write(item)
            file.write('\n')

elif answer == 'n':
    for pwd in range(number):
        password = ''
        for c in range(length):
            password  = random.choice(chars)
        print(password)
else:
    print('Couldn\'t understand that')
    quit()

CodePudding user response:

Create a list/set of already used passwords. Your code makes that a bit tricky because each created password is always instantly used. So you're gonna have to create a list where you store them in. Here is how you could do it (only the console print case):

import random
import string
import os

chars = string.ascii_letters   string.digits   string.punctuation
number = int(input('Enter the number of passwords you want: '))
length = int(input('Enter the length of the passwords: '))
print('Do you want to save the output in a file?(Y, n) ')
answer = input()
if answer == 'Y':
    ...
elif answer == 'n':
    already_used_pws = set()
    while len(already_used_pws) < number:
        password = ''
        for c in range(length):
            password  = random.choice(chars)
        if password in already_used_pws:
            continue
        print(password)
        already_used_pws.add(password)
else:
    print('Couldn\'t understand that')
    quit()

continue skips the iteration and doesnt print and add this password if it was used before, so it keeps being in the while loop until enough different passwords were generated.

CodePudding user response:

I don't reccomend store a password as plaintext because is easily accessible. Linux for exemple use crypt(5) to apply changes and store password in /etc/shadow like a hash. Just like I reccomend!

The Hash Function is a one way function with trap door to reverse or in other words: A function that can be computed by a string but cannot be reverted again to a string.

So to answer you the set() structure can store only unique values so you won't be repeat ones pass using this structure.

I refactor a little your code, keep learning:

import random, hashlib
from string import ascii_letters, digits, punctuation


def main():
    """Genertae random strings of char"""

    def get_input():
        number = int(input('Enter the number of passwords you want: '))
        length = int(input('Enter the length of the passwords: '))

        answer = input('Do you want to save the output in a file?(Y, n) ')
        assert (answer == 'n' or answer == 'Y')
        return number, length, answer


    def generate_pass(number):
        ret = set()
        for pwd in range(number):
            password = ''
            chars = ascii_letters   digits   punctuation
            
            for _ in range(length):
                password  = random.choice(chars)
            # or using list compreension
            # password = [random.choice(chars) for _ in range(length)]

            def hashed(text):
                return hashlib.sha224(text.encode('UTF-8')).hexdigest()

            password = "".join(password)
            password = str([password,hashed(password)])
            print(password)
            ret.add(password)

        return ret

    def add_to_file(store, fname):
        path = os.getcwd()
        fpath = os.path.join(path, fname)
        
        with open(fpath, 'w') as file:
            for item in store:
                file.write(str(item))
                file.write('\n')

    number, length, answer = get_input()
    if answer == 'Y':
        fname = input('Enter file name: ')   '.txt'
        password = generate_pass(number)
        add_to_file(password, fname)

    elif answer == 'n':
        password = generate_pass(number)
    else:
        print('Couldn\'t understand that')
        quit()
main()
  • Related