用星号屏蔽python中的用户输入

用星号屏蔽python中的用户输入,python,passwords,masking,raw-input,Python,Passwords,Masking,Raw Input,我试图用星号将用户键入的内容屏蔽为空闲,这样周围的人就看不到他们正在键入/已经键入的内容。我使用基本的原始输入来收集他们输入的内容 key = raw_input('Password :: ') 用户输入密码后理想的空闲提示: Password :: ********** 根据操作系统的不同,如何从用户输入中获取单个字符以及如何检查回车将有所不同 见此帖: 例如,在OSX上,您可以这样做: import sys, tty, termios def getch(): fd = sys

我试图用星号将用户键入的内容屏蔽为空闲,这样周围的人就看不到他们正在键入/已经键入的内容。我使用基本的原始输入来收集他们输入的内容

key = raw_input('Password :: ')
用户输入密码后理想的空闲提示:

Password :: **********

根据操作系统的不同,如何从用户输入中获取单个字符以及如何检查回车将有所不同

见此帖:

例如,在OSX上,您可以这样做:

import sys, tty, termios

def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

key = ""
sys.stdout.write('Password :: ')
while True:
    ch = getch()
    if ch == '\r':
        break
    key += ch
    sys.stdout.write('*')
print
print key

为了解决这个问题,我编写了这个小模块,在提示时屏蔽用户输入的密码。它适用于windows。代码如下:

from msvcrt import getch
import getpass, sys

def pyssword(prompt='Password: '):
    '''
        Prompt for a password and masks the input.
        Returns:
            the value entered by the user.
    '''

    if sys.stdin is not sys.__stdin__:
        pwd = getpass.getpass(prompt)
        return pwd
    else:
        pwd = ""        
        sys.stdout.write(prompt)
        sys.stdout.flush()        
        while True:
            key = ord(getch())
            if key == 13: #Return Key
                sys.stdout.write('\n')
                return pwd
                break
            if key == 8: #Backspace key
                if len(pwd) > 0:
                    # Erases previous character.
                    sys.stdout.write('\b' + ' ' + '\b')                
                    sys.stdout.flush()
                    pwd = pwd[:-1]                    
            else:
                # Masks user input.
                char = chr(key)
                sys.stdout.write('*')
                sys.stdout.flush()                
                pwd = pwd + char

免责声明:在终端中不提供asterix,但在jupyter笔记本中提供

下面的代码提供用asterix替换书面字符,并允许删除错误键入的字符。星号的数量反映键入字符的数量

import getpass
key = getpass.getpass('Password :: ')

用户按enter键后:


如果您想要在Windows/macOS/Linux和Python 2&3上运行的解决方案,可以安装
stdiomask
模块:

pip install stdiomask
getpass.getpass()
(位于Python标准库中)不同,
stdiomask
模块可以在键入时显示***掩码字符

用法示例:

>>> stdiomask.getpass()
Password: *********
'swordfish'
>>> stdiomask.getpass(mask='X') # Change the mask character.
Password: XXXXXXXXX
'swordfish'
>>> stdiomask.getpass(prompt='PW: ', mask='*') # Change the prompt.
PW: *********
'swordfish'
>>> stdiomask.getpass(mask='') # Don't display anything.
Password:
'swordfish'
不幸的是,这个模块与Python内置的
getpass
模块一样,不能在空闲或Jupyter笔记本中工作


更多细节在

我在尝试完成同样的壮举时偶然发现了这条线索。我知道这根线很旧,但如果有人需要它,我就是这样做的

我最终使用了这个软件包

这是我的解决方案,它打印星号并处理退格:

import sys, readchar

def passprompt(prompt: str, out = sys.stdout) -> str:
    out.write(prompt); out.flush()
    password = ""
    while True:
        ch = str(readchar.readchar(), encoding='UTF-8')
        if ch == '\r':
            break
        elif ch == '\b':
            out.write('\b \b')
            password = password[0:len(password)-1]
            out.flush()
        else: 
            password += ch
            out.write('*')
            out.flush()
    return password
我必须定期冲洗stdout才能让它工作

我的建议是--不要这样做

不要重新发明轮子,如果你想要“星星”,请使用密码助手


请参见

您将必须执行一些自定义标准输出重定向以使用星号屏蔽,但有一种更容易获取密码的方法。尽管您的代码片段可能会解决此问题,但您应该描述代码的用途(它如何解决此问题)。此外,您可能希望检查在终端或命令行上运行时,
getpass
完全隐藏输入。没有显示星号。这已经在Linux/MacOS上测试过了吗?这对我使用PyCharm控制台和Python 3.7不起作用,但是getpass.getpass也不起作用。两者都只是使用类似输入的东西。这似乎是PyCharm的一个限制,而不是您的库的问题。有没有办法让它在Jupyter笔记本中工作?不幸的是,它不可能在Jupyter笔记本中工作。它与命令行/终端窗口紧密相连,因此在浏览器(如Jupyter)中工作或提供自己的文本输出屏幕(如VS代码)的系统不会像命令行窗口那样执行删除文本的终端控制代码。谢谢。对于IDLE,在其回显和显示密码时似乎存在同样的问题。