Masking User Input In Python With Asterisks
Solution 1:
If you want a solution that works on Windows/macOS/Linux and on Python 2 & 3, you can install the stdiomask
module:
pip install stdiomask
Unlike getpass.getpass()
(which is in the Python Standard Library), the stdiomask
module can display *** mask characters as you type.
Example usage:
>>> stdiomask.getpass()
Password: *********
'swordfish'
>>> stdiomask.getpass(mask='X') # Change the mask character.
Password: XXXXXXXXX
'swordfish'
>>> stdiomask.getpass(prompt='PW: ', mask='*') # Change the prompt.
PW: *********
'swordfish'
>>> stdiomask.getpass(mask='') # Don't display anything.
Password:
'swordfish'
Unfortunately this module, like Python's built-in getpass
module, doesn't work in IDLE or Jupyter Notebook.
More details at https://pypi.org/project/stdiomask/
Solution 2:
To solve this I wrote this small module pyssword to mask the user input password at the prompt. It works with windows. The code is below:
from msvcrt import getch
import getpass, sys
def pyssword(prompt='Password: '):
'''
Prompt for a password and masks the input.
Returns:
the value entered by the user.
'''
if sys.stdin is not sys.__stdin__:
pwd = getpass.getpass(prompt)
return pwd
else:
pwd = ""
sys.stdout.write(prompt)
sys.stdout.flush()
while True:
key = ord(getch())
if key == 13: #Return Key
sys.stdout.write('\n')
return pwd
break
if key == 8: #Backspace key
if len(pwd) > 0:
# Erases previous character.
sys.stdout.write('\b' + ' ' + '\b')
sys.stdout.flush()
pwd = pwd[:-1]
else:
# Masks user input.
char = chr(key)
sys.stdout.write('*')
sys.stdout.flush()
pwd = pwd + char
Solution 3:
Depending on the OS, how you get a single character from user input and how to check for the carriage return will be different.
See this post: Python read a single character from the user
On OSX, for example, you could so something like this:
import sys, tty, termios
def getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
key = ""
sys.stdout.write('Password :: ')
while True:
ch = getch()
if ch == '\r':
break
key += ch
sys.stdout.write('*')
print
print key
Solution 4:
Disclaimer: does not provide the asterix in terminal, but it does so in jupyter notebook.
The below code provides replaces written characters with asterix and allow for deletion of wrongly typed characters. The number of asterixes reflects the number of typed characters.
import getpass
key = getpass.getpass('Password :: ')
And after the user press enter:
Solution 5:
I stumbled upon this thread while I was trying to preform the same feat. I know this thread is old, but if anyone else needs this - here is how I did it.
I ended up using readchar package.
Here is my solution, it prints asterisks and also handles backspaces:
import sys, readchar
def passprompt(prompt: str, out = sys.stdout) -> str:
out.write(prompt); out.flush()
password = ""
while True:
ch = str(readchar.readchar(), encoding='UTF-8')
if ch == '\r':
break
elif ch == '\b':
out.write('\b \b')
password = password[0:len(password)-1]
out.flush()
else:
password += ch
out.write('*')
out.flush()
return password
I had to regularly flush stdout for it to work.
Post a Comment for "Masking User Input In Python With Asterisks"