【问题标题】:How do I convert a password into asterisks while it is being entered?如何在输入密码时将密码转换为星号?
【发布时间】:2016-06-18 17:18:26
【问题描述】:

在 Python 中是否有一种方法可以将用户输入的字符转换为星号,就像在许多网站上都可以看到的那样?

例如,如果要求电子邮件用户登录他们的帐户,在输入密码时,密码不会显示为字符,而是在每次敲击后显示为 *,没有任何时间延迟。

如果实际密码是KermitTheFrog,输入时会显示为*************

【问题讨论】:

  • 这对我来说非常模糊 - 你的输入来源是什么?一个网页?终端? tkinter 文本区域?是的,但每个人都不一样
  • 我实际上是在为一个学校项目做这个,我是一个非常基础的程序员....但我会尝试使用 tkinter 文本区域,所以如果你能帮忙的话很棒

标签: python


【解决方案1】:

getpass(),一个隐藏用户输入的函数。

import getpass

password = getpass.getpass()
print(password)

【讨论】:

  • 是的,但是您知道在输入密码时可能会显示 (*) 而非什么都不会显示的内容吗?
  • 这完全隐藏了密码。它不显示星号 (*)。
  • 今天不是这样,在 Python 3.7 中,使用 Jupyter 实验室单元。我得到了要点(或者那些非常小的星号?)!
【解决方案2】:

如果您想要一个适用于 Windows/macOS/Linux 和 Python 2 和 3 的解决方案,您可以安装 pwinput 模块(以前称为 stdiomask):

pip install pwinput

getpass.getpass()(在 Python 标准库中)不同,pwinput 模块可以在您键入时显示 *** 掩码字符。它也是跨平台的,而getpass 仅适用于 Linux 和 macOS。

示例用法:

>>> pwinput.pwinput()
Password: *********
'swordfish'
>>> pwinput.pwinput(mask='X') # Change the mask character.
Password: XXXXXXXXX
'swordfish'
>>> pwinput.pwinput(prompt='PW: ', mask='*') # Change the prompt.
PW: *********
'swordfish'
>>> pwinput.pwinput(mask='') # Don't display anything.
Password:
'swordfish'

不幸的是,这个模块,就像 Python 的内置 getpass 模块一样,在 IDLE 或 Jupyter Notebook 中不起作用。

更多详情https://pypi.org/project/pwinput/

【讨论】:

  • 我不确定您所说的“getpass 仅适用于 Linux 和 macOS”是什么意思。 Python 的文档将getpass 描述为“便携式密码输入”。虽然它可能无法在所有平台上可靠地禁用回显,但它应该始终可用,必要时回退到从标准输入读取。
  • 啊,你是对的。我在考虑 getpass 以外的另一个模块。 getpass 模块不显示星号。
【解决方案3】:

如果您使用的是 Tkinter:

# For Python 2:
from Tkinter import Entry, Tk
# For Python 3
from tkinter import Entry, Tk

master = Tk()

Password = Entry(master, bd=5, width=20, show="*")
Password.pack()

master.mainloop()

在 shell 中,这是不可能的。但是,您可以编写一个函数来存储输入的文本并在调用时仅报告一串 *。 Kinda like this,不是我写的。我刚刚用谷歌搜索了它。

【讨论】:

    【解决方案4】:

    你可以这样做:

    # if getch module is available, then we implement our own getpass() with asterisks,
    # otherwise we just use the plain boring getpass.getpass()
    try:
        import getch
        def getpass(prompt):
            """Replacement for getpass.getpass() which prints asterisks for each character typed"""
            print(prompt, end='', flush=True)
            buf = ''
            while True:
                ch = getch.getch()
                if ch == '\n':
                    print('')
                    break
                else:
                    buf += ch
                    print('*', end='', flush=True)
            return buf
    except ImportError:
        from getpass import getpass
    

    【讨论】:

    • 可能需要处理退格键和 Ctrl + U
    【解决方案5】:

    首先安装库:

    pip install stdiomask
    

    请注意,您安装的是 std io mask 而不是 studiomask...

    然后代码是:

    password = stdiomask.getpass() # It will ask to enter password and display * on the screen
    
    print(password)
    

    这是输出:

    Password: *****
    google
    

    【讨论】:

    • 次要注意:stdiomask 模块现在称为 pwinput。有关详细信息,请参阅此问题中的其他答案。
    【解决方案6】:

    对于真正希望出现星号的任何人,这是对Tigran Aivazian's answer 的改进。这个版本导入了内置的msvcrt.getch,在点击“Enter/Return”时添加了不同行尾的情况,并包括支持退格的逻辑,以及Ctrl+C(键盘中断):

    try:
        from msvcrt import getch
        def getpass(prompt):
            """Replacement for getpass.getpass() which prints asterisks for each character typed"""
            print(prompt, end='', flush=True)
            buf = b''
            while True:
                ch = getch()
                if ch in {b'\n', b'\r', b'\r\n'}:
                    print('')
                    break
                elif ch == b'\x08': # Backspace
                    buf = buf[:-1]
                    print(f'\r{(len(prompt)+len(buf)+1)*" "}\r{prompt}{"*" * len(buf)}', end='', flush=True)
                elif ch == b'\x03': # Ctrl+C
                    raise KeyboardInterrupt
                else:
                    buf += ch
                    print('*', end='', flush=True)
            return buf.decode(encoding='utf-8')
    except ImportError:
        from getpass import getpass
    

    请随时提出任何其他更改或改进方法;我很快就完成了这些更改,尤其是使用 Backspace 逻辑。

    【讨论】:

      【解决方案7】:

      在 python 中使用getpass 时,没有任何指示显示密码输入。

      这可以通过这个简单的解决方案来解决:

      只需将链接中提供的 ‘getpass_ak.py’ 模块复制到 python 的 Lib 文件夹即可。

      https://starrernet.wixsite.com/analytix/python-coder

      使用以下代码:

      import getpass_ak
      
      a = (getpass_ak.getpass('password: '))
      

      这会将 * 添加到您的密码输入中。

      【讨论】:

        【解决方案8】:

        我已将 @Tigran Aivazian@Ahndwoo 的答案组合成完全可行的解决方案:

        • !添加了退格 {b'\x08', b'\x7f'}: # Backspace 的附加代码
        • 对于Ctrl+C 组合,使用静默返回。 raise KeyboardInterrupt 现在已注释,但可以取消注释以引发错误。
        # if getch module is available, then we implement our own getpass() with asterisks,
        # otherwise we just use the plain boring getpass.getpass()
        try:
            from getch import getch
            def getpass(prompt):
                """Replacement for getpass.getpass() which prints asterisks for each character typed"""
                print(prompt, end='', flush=True)
                buf = b''
                while True:
                    ch = getch().encode()
                    if ch in {b'\n', b'\r', b'\r\n'}:
                        print('')
                        break
                    elif ch == b'\x03': # Ctrl+C
                        # raise KeyboardInterrupt
                        return ''
                    elif ch in {b'\x08', b'\x7f'}: # Backspace
                        buf = buf[:-1]
                        print(f'\r{(len(prompt)+len(buf)+1)*" "}\r{prompt}{"*" * len(buf)}', end='', flush=True)
                    else:
                        buf += ch
                        print('*', end='', flush=True)
        
                return buf.decode(encoding='utf-8')
        except ImportError:
            from getpass import getpass
        
        password = getpass('Enter password: ')
        print(password)
        

        【讨论】:

        【解决方案9】:

        我自己的建议是——不要这样做!

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

        改为执行以下伪代码...如果设置了 TTY_ASSPASS 环境变量 - 调用该密码帮助程序。有一个可用的数字,包括“systemd-ask-password” 如果有 TTY - 回退读取不回显 (getpass.getpass()) 如果没有 TTY, - 回退只需读取带有 rstrip()

        这不仅可以让用户选择密码输入程序(通过环境变量(或其他配置),还可以让他们替代其他密码来源,例如 GUI 输入,或从预先打开的密钥环中收集密码密码守护进程,或其他地方

        不要限制或以其他方式限制密码的来源!

        有关密码助手的说明,请参阅..https://antofthy.gitlab.io/info/crypto/passwd_input.txt

        对于一个shell脚本密码助手https://antofthy.gitlab.io/software/#askpass_stars

        看起来 Andrei Krivoshei 的答案已经开始了,结果非常相似,但仍处于起步阶段。

        【讨论】:

          【解决方案10】:

          您可能需要检查getpass 功能。

          提示用户输入密码而不回显。提示用户 使用字符串提示,默认为“密码:”。在 Unix 上, 提示被写入类文件对象流。流默认为 控制终端 (/dev/tty) 或者如果它不可用 sys.stderr(此参数在 Windows 上被忽略)。

          注意:此模块模仿 unix 密码提示,不显示星号。

          用法:

          import getpass
          getpass.getpass()
          

          【讨论】:

          • 伙计们,你被打败了几秒钟,是吗? ;)
          猜你喜欢
          • 1970-01-01
          • 2017-01-23
          • 2012-08-09
          • 2012-06-15
          • 1970-01-01
          • 1970-01-01
          • 2015-11-04
          • 2012-05-19
          • 2017-07-24
          相关资源
          最近更新 更多