How can a password input be done in python with printing an asterisk for every character of the user? How can a password input be done in python with printing an asterisk for every character of the user? python python

How can a password input be done in python with printing an asterisk for every character of the user?


See the first answer there :

What's the simplest way of detecting keyboard input in python from the terminal?

Just print stars '*' or anything when a key is pressed.

All credit obviously goes to Phylliida for the research.


You may want to look at how jupyter/ipython implemented this. I'm getting a dot displayed immediately for every character typed using getpass().

enter image description here


I wrote a module to illustrate roughly how you do it platform independently.

#!/usr/bin/python2def _masked_input_unix(prompt="Password: ", mask="*"):    pw = ""    # save terminal settings    fd = sys.stdin.fileno()    old = termios.tcgetattr(fd)    new = termios.tcgetattr(fd)    # setup 'cbreak' mode    new[3] = new[3] & ~termios.ECHO    new[3] = new[3] & ~termios.ICANON    new[6][termios.VMIN] = '\x01'    new[6][termios.VTIME] = '\x00'    try:        termios.tcsetattr(fd, termios.TCSADRAIN, new)        print prompt,        # Read the password        while True:            c = sys.stdin.read(1)            # submit chars            if c == '\r' or c == '\n':                sys.stdout.write("%s" % (c))                break            # delete chars            elif c == '\b' or c == '\x7f':                if len(pw) > 0:                    pw = pw[:-1]                    sys.stdout.write("%s" % ('\b \b'))            # password chars            else:                pw += c                sys.stdout.write("%s" % (mask))    finally:        # ensure we reset the terminal        termios.tcsetattr(fd, termios.TCSADRAIN, old)    return pwdef _masked_input_win(prompt="Password: ", mask='*'):    pw = ""    while True:        c = msvcrt.getch()        # submit chars        if c == '\r' or c == '\n':            while msvcrt.kbhit():                msvcrt.getch()            print            break        elif c == '\x03':            raise KeyboardInterrupt        # delete chars        elif c == '\b' or c == '\x7f':            if len(pw) > 0:                pw = pw[:-1]                msvcrt.putch('\b')                msvcrt.putch(' ')                msvcrt.putch('\b')        # password chars        else:            pw += c            msvcrt.putch(mask)    return pw## initialize windows or posix function pointermasked_input = Nonetry:    import msvcrt    masked_input = _masked_input_winexcept ImportError:    import sys, termios    masked_input = _masked_input_unixif __name__ == "__main__":    p = masked_input()    print "Password is:", p

And this works for single-byte encodings. Adding unicode support is non-trivial. I suspect unicode doesn't work well with the getpass module on Windows. (NOTE: it is not as simple as changing everything to unicode strings and using getwch())