Reputation: 1
I have been trying to create a password generator in python using the secrets module. I first ask the user the desired length of the password, and then chose randomly between 3 lists of characters (letters, numbers, symbols). I then print the results one by one through a loop.
My problem is that the program works fine until around 12 characters asked by the user. I then get the following error IndexError: list index out of range
and after searching for hours, I can't manage to find an answer.
Sorry if the question seems basic, but I'm still a beginner, and only want to improve!
Here's my code :
import secrets
# importing modules
doRun = True
while doRun:
length = int(input("How many characters do you want you password to have ? "))
# Asking the user for the length of the password
letCar = ["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"]
# List for characters
numCar = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
# List for numbers
symCar = ["!", "@", "?"]
# List for symbols
password = []
# Initializing list for password
for i in range(0, length):
selector = secrets.randbelow(3)
# Randomly choosing from which list to pick
if selector == 0:
# Characters list
chosenCar = secrets.choice(letCar)
password.append(chosenCar)
letCar.remove(chosenCar)
elif selector == 1:
# Numbers list
chosenCar = secrets.choice(numCar)
password.append(chosenCar)
numCar.remove(chosenCar)
elif selector == 2:
# Symbols list
chosenCar = secrets.choice(symCar)
password.append(chosenCar)
symCar.remove(chosenCar)
print("password is : ", end="")
for i in range(len(password)):
print(password[i], end="")
print()
doRun = input("Again ? (Yes --> True // No --> False) : ")
The errors are :
Traceback (most recent call last):
File "E:\Bureautique\Outils\Programmation\Python\Projects\PWHash\main.py", line 35, in <module>
chosenCar = secrets.choice(symCar)
File "C:\Users\Arthur\AppData\Local\Programs\Python\Python39\lib\random.py", line 347, in choice
return seq[self._randbelow(len(seq))]
IndexError: list index out of range
Thank you for your help!
Upvotes: 0
Views: 535
Reputation: 11
The problem is that an item from symCar is deleted every time an item is selected from it. This empties the list after three repetitions. To fix the problem, you could remove the .remove lines. Although this allows for multiple of a single character to be included in your password, this helps keep it unpredictable.
Another option is to add a way for the lists to refill after all of their items have been deleted. An example of this is shown below.
if symCar == []:
symCar = ["!", "@", "?"]
Upvotes: 0
Reputation: 31
I don't know if it's what you're looking for but that's how it worked for me
for i in range(0, length):
selector = secrets.randbelow(3)
# Randomly choosing from which list to pick
if selector == 0:
# Characters list
chosenCar = secrets.choice(letCar[i])
password.append(chosenCar)
letCar.remove(chosenCar)
elif selector == 1:
# Numbers list
chosenCar = secrets.choice(numCar[i])
password.append(chosenCar)
numCar.remove(chosenCar)
Upvotes: 0
Reputation: 29
I think it's because you're removing items from the Car lists, so that when a Car is chosen enough times, in the case of the symCars, the line where your program crashed, only 3, and it is then an empty list, so if the Car is selected again there's nothing in the list for the secrets module to find
Upvotes: 1