4

I want to write a small project,it needs you to input your id and passwd,but i need a function to replace the passwd with '*' while you inputing passwd,i only know the raw_input() can input something,so i cannot solve the problem. how to write the function?

evbo
  • 157
  • 4
  • 14
  • @lanAuld,oh,but i need to show " * " while you input your passwd rather than hiding only. – evbo Jul 08 '15 at 13:53

3 Answers3

6

Try this:

import getpass
pw = getpass.getpass()
Hrvoje
  • 362
  • 2
  • 6
  • but how to show ' * ' while i input pwd rather than show nothing. – evbo Jul 08 '15 at 08:30
  • I don't think there is a parameter that can make getpass output asterisks, but you could always implement your own if you *really* need to. Take a look at getpass.py source and use that as a starting point. – Hrvoje Jul 08 '15 at 08:47
  • It is actually a security improvement when you don't show the number of characters of that password. However, you can check out this previous answer for echoing the input with a *. http://stackoverflow.com/a/10991348/5066845 – Steven Correia Jul 08 '15 at 09:01
2

If all else fails, you could modify the getpass library (you can't sub-class it, unfortunately).

e.g. The code for windows (source):

def win_getpass(prompt='Password: ', stream=None):
 """Prompt for password with echo off, using Windows getch()."""
    if sys.stdin is not sys.__stdin__:
        return fallback_getpass(prompt, stream)
    import msvcrt
    import random
    for c in prompt:
        msvcrt.putwch(c)
    pw = ""
    while 1:
        c = msvcrt.getwch()
        if c == '\r' or c == '\n':
            break
        if c == '\003':
            raise KeyboardInterrupt
        if c == '\b':
            pw = pw[:-1]
        else:
            pw = pw + c
            stars = random.randint(1,3)
            for i in range(stars):
                msvcrt.putwch('*') #<= This line added
    msvcrt.putwch('\r')
    msvcrt.putwch('\n')
    return pw

Should print a '*' for every character entered.

Edit:

getpass() is stated to be incompatible with Python 2, and on Python 2 (At least on my machine), putwch() gives TypeError: must be cannot convert raw buffers, not str.

This can be resolved by changing:

msvcrt.putwch(c) to msvcrt.putwch(unicode(c))

and

msvcrt.putwch('str') to msvcrt.putwch(u'str')

Or simply replacing putwch() with putch() if you don't need to deal with unicode.

Edit2:

I've added a random element so that it will print 1-3 stars for each keypress

SiHa
  • 7,830
  • 13
  • 34
  • 43
  • thank u,it works,but there is something wrong,line 7,19,20,21,they cannot be str,after i run it ,the dos told me. – evbo Jul 08 '15 at 09:45
  • Funny, `msvcrt.putwch()` also gives me `TypeError: must be cannot convert raw buffers, not str`. Are you using Python 2, by any chance? – SiHa Jul 08 '15 at 11:02
  • I've added to the answer above. If you make the suggested changes, it should work with Python 2.7. – SiHa Jul 08 '15 at 14:34
  • `msvcrt.putwch()` requires a unicode string. In python 2 you need to do `msvcrt.putwch(u'\r')` rather than `msvcrt.putwch('\r')` – nabin-info Nov 22 '16 at 20:04
  • People have already done it... stackoverflow.com/a/67327327/701532 – anthony Apr 30 '21 at 02:36
  • @anthony why are you spamming a six-year-old answer with a link to your own non-answer? – SiHa Apr 30 '21 at 07:06
0

I came across this post after searching for ways to make python print '*' instead of blank space while accepting password and i found SiHa's answer really helpful but it doesn't erase the '*' already printed if we press backspace, so again i came across this another post : How to have password echoed as asterisks, the combined code :

def win_getpass(prompt='Password: ', stream=None):
"""Prompt for password with echo off, using Windows getch()."""
if sys.stdin is not sys.__stdin__:
    return fallback_getpass(prompt, stream)
import msvcrt
import random
for c in prompt:
    msvcrt.putch(c)
pw = ""
while 1:
    c = msvcrt.getwch()
    if c == '\r' or c == '\n':
        break
    elif c == '\003':
        raise KeyboardInterrupt
    elif c == '\b':
        if pw != '': # If password field is empty then doesnt get executed
            pw = pw[:-1]
            msvcrt.putwch(u'\x08')
            msvcrt.putch(' ')
            msvcrt.putwch(u'\x08')
    else:
        pw = pw + c
        msvcrt.putch('*') #<= This line added
msvcrt.putch('\r')
msvcrt.putch('\n')
return pw
Community
  • 1
  • 1
Kael
  • 92
  • 1
  • 8