问题:程序员希望用户输入密码。getpass()函数很适合用于此目的,但它的使用有一个缺点:在输入密码时,不会将任何内容输出到stdout。
这个问题:当用户输入的每个字符都打印出星号时,如何实现getpass()?(当然,退格键-理想情况下是pos1和end -应该相应地处理。)
动机:社区中有一些人不理解为什么要问这个问题。然后引用getpass(),a)以这种方式忽略手头的任务,b)没有考虑到引用不会回答问题。s.o.可能想要打印星号的原因是为了方便用户:他们在输入密码时会得到直接的视觉反应。因此,他们不会因为按键而感到困惑,而且-在他们的眼睛里-似乎什么都没有发生。
迈向解决方案的一步:
让我在这里介绍解决方案的第一步。请帮助我们将其演变为一个真正的解决方案。
有一个名为getch的模块,它似乎允许从标准输入中逐个字符地读取。Backspace -非常奇怪-映射到一个整数值127,但这样的解决方案可能看起来像这样:
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
但是这段代码有一些缺点。首先,如果s.o.进入退格符,我对c不是'\b‘感到非常困惑。也许s.o.对此有一个解释?其次,只处理ASCII字符,至少在Linux上是这样。我不知道这里的窗口,但如果按下A-Z0-9以外的字符,c= getch.getch()行将抛出异常。getch()似乎不能处理变音和其他类型的字符,至少在某种程度上是这样。
要进入解决方案输入,应解决以下问题:
对于非ASCII characters?
发布于 2016-11-26 03:20:28
看这里的第一个答案:
What's the simplest way of detecting keyboard input in python from the terminal?
当一个键被按下时,只需打印星号'*‘或任何东西。
显然,所有的功劳都归功于Phylliida的研究。
发布于 2016-11-22 07:33:27
您可能想看看jupyter/ipython是如何实现这一点的。对于使用getpass()键入的每个字符,我都会立即显示一个点。
发布于 2016-11-22 02:23:57
注意:我的另一个答案包含了以独立于平台的方式完成这项工作的python2代码。
安全的平台无关方式将设置与getpass.getpass()
完全相同的所有内容,因此请查看源代码(对于我来说是/usr/lib/python2.7/getpass.py
);它非常简单。
至于星星的回声..。
win_getpass()
已经在逐个读取字符,只需在循环中回显一些*
即可。您可能需要使用msvcrt.getwch()
而不是msvcrt.getch()
,但这意味着python getpass
模块有一个bug。
unix_getpass()
更棘手。您需要为终端设置cbreak
,类似于已经禁用ECHO
的方式(请参阅https://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw)。然后,您必须在循环中使用read(1)
(类似于win_getpass()
),而不是_raw_input()
正在使用的readline()
。
一旦您逐个字节地阅读,您就可以经历确定什么构成“letter”的痛苦。这取决于编码,甚至长度可能是可变的(在UTF-8的情况下)。
https://stackoverflow.com/questions/40651085
复制相似问题