The problem: Programmers want users to input passwords. The getpass() function is nice for this purpose, but its use has a drawback: While entering a password nothing is printed to stdout.
The question: How can a getpass() be implemented while asterisks are printed for every character typed by a user? (Of course backspace - and ideally pos1 and end - should be taken care of accordingly.)
The motivation: There have been people in the community not understanding why this question has been asked. And then referred to getpass() with a) this way ignoring the task at hand and b) without thinking about that there reference would not answer the question. The reason why s.o. might want to have asterisks printed is for convenience of users: They get a direct visual response during password input. Therefor they do not get confused by pressing keys and - to there eyes - nothing seems to be happening.
A step towards a solution:
Let me present a first step towards a solution here. Please help in order to evolve it into a real solution.
There is a module named getch which seems to allow reading character by character from stdin. Backspace is - quite strangely - mapped to an integer value of 127, but such a solution could then look like this:
def readLineWithAsterisks():
sBuffer = ''
while True:
c = getch.getch()
if c == '\n':
return sBuffer
elif ord(c) == 127:
if len(sBuffer) > 0:
sys.stdout.write('\x08 \x08')
sys.stdout.flush()
sBuffer = sBuffer[0:-1]
continue
else:
sys.stdout.write('*')
sys.stdout.flush()
sBuffer += c
But this code has some drawbacks. First I'm very much confused about c not being '\b' if s.o. entered a backspace. Maybe s.o. has an explanation for this? Second only ASCII characters are processed, at least on Linux. I don't know about Windows here, but if a character other than A-Z0-9 is pressed, the line c = getch.getch() will throw an exception. getch() does not seem to be able to process umlauts and other kinds of characters, at least to some extent.
To come to solution input the following issues should be addressed:
- How can a read from stdin be done character by character in regard to non-ASCII characters?
- How can this be done in a platform independent way?
- How can this been done safely (without security issues)? (getpass somehow seems to address this but I don't fully understand how.)