Search code examples
pythonwindowsrandomgetpasswd

Generate and Require Input of a Randomly-Generated Password


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.


Solution

  • 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: ")