Generate and Require Input of a Randomly-Generated Password

162 Views Asked by At

My program needs to remember a specific pre-determined password which has been assigned to a variable so that the user input must match it.

import random

password = [chr(random.randint(33, 126)) for x in range(6)]

print("Your password is: {}".format(" ".join(password)))

import getpass

pswd = getpass.getpass(password)

if (pswd == password):
   print("Access granted")
else:
   print("Access denied")

In the code they receive their password and then they need to input it. I've removed a massive chunk of irrelevant coding and so the main thing is that the user gets their password and later on they have to input it. So the password is a set of random characters, which then is the password that the user needs to remember and input when required.

It's not working, and I was wondering if someone could help please.

Also, is there a way to remove the red writing (GetPassWarning) that appears on the shell due to the importation of getpass.getpass()?

Thanks.

3

There are 3 best solutions below

5
On BEST ANSWER

There are a couple of problems here, but you're on the right track!

Try this:

import random
import getpass

password = "".join([chr(random.randint(33, 126)) for x in range(6)])

print("Your password is: {}".format(password))

pswd = getpass.getpass("Enter password: ")

if (pswd == password):
   print("Access granted")
else:
   print("Access denied")

First, you need to use "".join()" instead of " ".join(), unless you want a space between each character. Second, you need to use "".join()" at the point where you define password, because it needs to be a string, equivalent to what you want the user to enter, not a list.

Thirdly, the argument for getpass.getpass() is the prompt to ask the user to enter the password, not the password itself. getpass() doesn't need to know what the password is; it just helps you hide input-echoing from the user while they enter their password.

getpass.getpass([prompt[, stream]])

Prompt the user for a password without echoing. The user is prompted using the string prompt, which defaults to 'Password: '. On Unix, the prompt is written to the file-like object stream. stream defaults to the controlling terminal (/dev/tty) or if that is unavailable to sys.stderr (this argument is ignored on Windows).

Edit

The red error you're seeing is because of this (from the getpass() manual page linked above):

If echo free input is unavailable getpass() falls back to printing a warning message to stream and reading from sys.stdin and issuing a GetPassWarning.

This is likely a Windows-only problem, and under a Linux / POSIX environment, input would be hidden.

To fix this error under Windows, getpass() tries to use the msvcrt module. I don't have a Windows machine to test with, but try running import msvcrt at a Python prompt or in a script and see if it works or fails, and post any errors you see in the comments. It looks like you'd get this error under Windows only if msvcrt fails to import, or if sys.stdin isn't functioning as expected.

Also, as @Jasper Bryant-Greene awesomely-suggested in his answer, we can use a warnings filter to hide the warning, if the underlying issue with msvcrt cannot be fixed:

import warnings

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    pswd = getpass.getpass("Enter password: ")
4
On

Set password to the string that you get after joining, so you can compare it to the string that the user enters.

import random

password = " ".join([chr(random.randint(33, 126)) for x in range(6)])

print("Your password is: {}".format(password)

import getpass

pswd = getpass.getpass("Enter your password: ")

if (pswd == password):
   print("Access granted")
else:
   print("Access denied")
2
On

Instead of:

password = [chr(random.randint(33, 126)) for x in range(6)]
print("Your password is: {}".format(" ".join(password))

… use:

password = "".join(chr(random.randint(33, 126)) for x in range(6))
print("Your password is: {}".format(password))

so that password is a str rather than a list.

To prevent printing the password again as part of the password prompt, and suppress the GetPassWarning (suppression only necessary if you can’t fix the problem, which as mentioned in another post could be related to the msvcrt module), you can change:

pswd = getpass.getpass(password)

… to:

import warnings

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    pswd = getpass.getpass("Enter password:")

(By passing password as the first argument to getpass.getpass, you’re currently telling it to use the password itself as the password prompt.)