I came across a project geared toward starters like myself - creating a CLI passwordcreator.
I have with the help of a few guides completed the generator and added a few of my own features, however there is one feature I can't seem to figure out how to implement; saving the output to a file.
In the terminal the passwords shows up perfectly fine line by line, however if I try to save the output to a file it only saves the last password, and it seperates each letter by line.
My code is below, together with examples of output from both the terminal and a .txt file.
import string
import random
from os import system, name
letters = list(string.ascii_letters)
digits = list(string.digits)
special_characters = list("!@#$%^&*()£")
characters = list(string.ascii_letters string.digits '!@#$%^&*()£')
def clear():
if name == 'nt':
_ = system('CLS')
else:
_ = system('clear')
def generate_random_password():
clear()
length = int(input("Enter password length: "))
amount = int(input('Enter amount of passwords: '))
letters_count = int(input("Enter letter count: "))
digits_count = int(input("Enter digits count: "))
special_characters_count = int(input("Enter special characters count: "))
character_count = letters_count digits_count special_characters_count
if character_count > length -1:
print("Characters total count is greater than desired password length")
exit()
clear()
password = []
print("Following passwords saved to Passwords.txt, please move the file before generating new passords, as a new generation will overwrite existing")
print('\n')
for pwd in range(amount):
password = []
for c in range(digits_count):
password.append(random.choice(digits))
for c in range(letters_count):
password.append(random.choice(letters))
for c in range(special_characters_count):
password.append(random.choice(special_characters))
if character_count < length:
random.shuffle(characters)
for c in range(length - character_count):
password.append(random.choice(characters))
random.shuffle(password)
if str(password) < str(length):
return()
else:
print("".join(password))
with open('Passowrds.txt', 'w') as file:
for line in ("".join(password)):
file.write(line)
file.write('\n')
#file = open('Passwords.txt', 'w')
#str1 = repr(password)
#file.write('\n' str1 '\n')
#file.close
#f = open('Passwords.txt', 'r')
#if f .mode == 'r':
# contents=f.read
generate_random_password()
This is what the output from the terminal looks like:
Following passwords saved to Passwords.txt, please move the file
before generating new passords, as a new generation will overwrite
existing
gtBVA3QDcUohDc£TfX(zVt*24
KD8PnMD£)25hvHh#3xj79$qZI
Dx^*2£srcLvRx5g3B3(nq0H&9
&r6^3MEsaV1RuDHzxq*(h3nO)
However what is saved in the .txt file looks like this:
&
r
6
^
3
M
E
s
a
V
1
R
u
D
H
z
x
q
*
(
h
3
n
O
)
CodePudding user response:
The reason why your script is saving only 1 password is because you are opening the file to be written (which clears the contents of the file) for every password you are generating.
You want to do something along the lines of:
passwords = []
for _ in range(num_passwords):
password = ...
passwords.append(password)
with open("password.txt", "w") as f:
f.writelines(passwords)
Although there is nothing terrible about the way you're using the random library, I recommend taking a look at random.sample
(without replacement) or random.choices
(with replacement).
Also, using shuffling your characters
list isn't adding additional randomness to your random.choice
.
You don't have to convert the strings to lists in order to run choice:
>>> import random
>>> random.choice("abc")
'b'
A fuller example:
def generate_random_password():
clear()
length = int(input("Enter password length: "))
amount = int(input("Enter amount of passwords: "))
letters_count = int(input("Enter letter count: "))
digits_count = int(input("Enter digits count: "))
special_characters_count = int(input("Enter special characters count: "))
character_count = letters_count digits_count special_characters_count
if character_count > length - 1:
print("Characters total count is greater than desired password length")
exit()
clear()
passwords = []
for _ in range(amount):
chosen_digits = random.choices(digits, k=digits_count)
chosen_letters = random.choices(letters, k=letters_count)
chosen_special_characters = random.choices(
special_characters, k=special_characters_count
)
extra_characters_count = length - character_count
extra_characters = random.choices(characters, k=extra_characters_count)
password = (
chosen_digits
chosen_letters
chosen_special_characters
extra_characters
)
random.shuffle(password)
passwords.append("".join(password))
with open("Passwords.txt", "w") as f:
f.writelines(passwords)