简体   繁体   中英

Random password generator only generating limited amount of characters

I am learning Python and today I decided to try and have a go at creating a random password generator. The code generates a random amount of letters, then numbers, then symbols, (based on the amount the user specifies). These values are all stored in a list where they are each concatenated with one another. From there the values are all re-randomized to produce a final password.

If I try to use large numbers as input (above around 40) it errors. It also doesn't always produce the specified length. If I input 30 letters, 30 numbers, and 30 symbols, for example, the final password is short of 90 by about 10 if I remember correctly. Any help would be appreciated--I think the fix is simple just having trouble finding it.

Here is my code: 


import random
import itertools

# lists
chars = ['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']
nums = ['0','1','2','3','4','5','6','7','8','9']
syms = ['!','@','#','$','%','^','&','*','+','_']

# inputs
print("Python Password Generator : \n")
charAmount = int(input("How many letters would you like to have in your password? : "))
numAmount = int(input("How many numbers? : "))
symAmount = int(input("How many symbols? : "))

# random num/sym/char

randomNum = ""
for num in nums :
  if int(num) < numAmount :
    randomNum += nums[random.randint(0,9)]


randomSym = ""
for sym in range(0, symAmount):
  if sym < symAmount :
    randomSym += syms[random.randint(0,9)]


randomChar = ""
for char in range(0, charAmount) :
  if sym < charAmount :
    randomChar += chars[random.randint(0, 25)]


# Final Password generator
generatorList = list(itertools.chain(randomNum,randomSym,randomChar))

Password = ""
tot = len(generatorList)
for word in generatorList:
      Password += generatorList[random.randint(0,tot)]

print(f"Your new password is : {Password}")

There's two issues with your code:

  1. The if statements aren't necessary, because the number of iterations is limited by the for loop already.
  2. random.randint() has inclusive arguments on both sides. So, in this code snippet:
Password = ""
tot = len(generatorList)
for word in generatorList:
      Password += generatorList[random.randint(0,tot)]

.randint() can return tot , which is out of range for the generatorList .

Here is a code snippet that resolves both of these issues:

import random
import itertools
# lists
chars = ['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']
nums = ['0','1','2','3','4','5','6','7','8','9']
syms = ['!','@','#','$','%','^','&','*','+','_']

# inputs
print("Python Password Generator : \n")
charAmount = int(input("How many letters would you like to have in your password? : "))
numAmount = int(input("How many numbers? : "))
symAmount = int(input("How many symbols? : "))

# random num/sym/char

randomNum = ""
for num in range(numAmount) :
    randomNum += nums[random.randint(0,9)]

randomSym = ""
for sym in range(0, symAmount):
    randomSym += syms[random.randint(0,9)]

randomChar = ""
for char in range(0, charAmount) :
    randomChar += chars[random.randint(0, 25)]

# Final Password generator
generatorList = list(itertools.chain(randomNum,randomSym,randomChar))

Password = ""
tot = len(generatorList)
for word in generatorList:
     Password += generatorList[random.randint(0,tot - 1)]

print(f"Your new password is : {Password}")

Those fix your immediate issues, but there's also a few extra improvements we could make:

  1. Rather than list out the lowercase characters and digits, we can use constants from the string module.
  2. Repeated string concatenation is inefficient . Use .join() instead.
  3. Use random.choices() to pick the characters to add to our password, then shuffle them all at the end.

With all this in mind, we get the following:

import random
import string

chars = string.ascii_lowercase
nums = string.digits
syms = ['!','@','#','$','%','^','&','*','+','_']

print("Python Password Generator : \n")
char_amount = int(input("How many letters would you like to have in your password? : "))
num_amount = int(input("How many numbers? : "))
sym_amount = int(input("How many symbols? : "))

password_characters = random.choices(chars, k=char_amount) + random.choices(nums, k=num_amount) + random.choices(syms, k=sym_amount)
random.shuffle(password_characters)

password = ''.join(password_characters)
print(f"Your new password is : {password}")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM