Skip to content

Instantly share code, notes, and snippets.

@andreasf
Last active July 28, 2016 08:24
Show Gist options
  • Save andreasf/9056462 to your computer and use it in GitHub Desktop.
Save andreasf/9056462 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
def main():
print("password is: " + get_passwd())
def get_passwd():
"""
getpass alternative that prints asterisks after each character.
only tested with utf-8 locales.
"""
import termios
import sys
import tty
import locale
# get locale for decoding input
locale.setlocale(locale.LC_ALL, '')
loc, encoding = locale.getlocale()
# prepare terminal states
fd = sys.stdin.fileno()
term_state = termios.tcgetattr(fd)
new_state = termios.tcgetattr(fd)
new_state[3] = new_state[3] & ~termios.ECHO
passwd = b""
ctrl_c = False
try:
# disable echo
termios.tcsetattr(fd, termios.TCSADRAIN, new_state)
tty.setraw(fd)
done = False
while not done:
try:
# Python 3
c = sys.stdin.buffer.read(1)
except AttributeError:
# Python 2
c = sys.stdin.read(1)
# \n or \r, end of password
if ord(c) == 10 or ord(c) == 13:
done = True
# ctrl+c
elif ord(c) == 3:
done = True
ctrl_c = True
# backspace
elif ord(c) == 127:
passwd = passwd[:-1]
sys.stdout.write("\b \b")
sys.stdout.flush()
# default: append
else:
passwd += c
try:
# if this fails, we don't have a full (utf-8) character
passwd.decode(encoding)
sys.stdout.write("*")
sys.stdout.flush()
except UnicodeDecodeError:
pass
finally:
sys.stdout.write("\r\n")
sys.stdout.flush()
termios.tcsetattr(fd, termios.TCSADRAIN, term_state)
pass
if ctrl_c:
sys.exit(0)
return passwd.decode(encoding)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment