首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在python中输入密码,并为用户的每个字符打印一个星号?

如何在python中输入密码,并为用户的每个字符打印一个星号?
EN

Stack Overflow用户
提问于 2016-11-17 17:27:23
回答 8查看 8.7K关注 0票数 23

问题:程序员希望用户输入密码。getpass()函数很适合用于此目的,但它的使用有一个缺点:在输入密码时,不会将任何内容输出到stdout。

这个问题:当用户输入的每个字符都打印出星号时,如何实现getpass()?(当然,退格键-理想情况下是pos1和end -应该相应地处理。)

动机:社区中有一些人不理解为什么要问这个问题。然后引用getpass(),a)以这种方式忽略手头的任务,b)没有考虑到引用不会回答问题。s.o.可能想要打印星号的原因是为了方便用户:他们在输入密码时会得到直接的视觉反应。因此,他们不会因为按键而感到困惑,而且-在他们的眼睛里-似乎什么都没有发生。

迈向解决方案的一步:

让我在这里介绍解决方案的第一步。请帮助我们将其演变为一个真正的解决方案。

有一个名为getch的模块,它似乎允许从标准输入中逐个字符地读取。Backspace -非常奇怪-映射到一个整数值127,但这样的解决方案可能看起来像这样:

代码语言:javascript
运行
复制
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?

  • How,如何逐个字符地从标准输入读取?
  • 如何以独立于平台的方式完成?
  • 如何安全地完成(没有安全问题)?(getpass似乎以某种方式解决了这个问题,但我并不完全理解它是如何解决的。)
EN

回答 8

Stack Overflow用户

发布于 2016-11-26 03:20:28

看这里的第一个答案:

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

当一个键被按下时,只需打印星号'*‘或任何东西。

显然,所有的功劳都归功于Phylliida的研究。

票数 5
EN

Stack Overflow用户

发布于 2016-11-22 07:33:27

您可能想看看jupyter/ipython是如何实现这一点的。对于使用getpass()键入的每个字符,我都会立即显示一个点。

票数 2
EN

Stack Overflow用户

发布于 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的情况下)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40651085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档