【问题标题】:Password Testing in PythonPython中的密码测试
【发布时间】:2017-07-19 00:30:30
【问题描述】:

我有以下代码来测试密码强度:

import string
def golf(password):
    if len(password) >= 10:
        if any(char.isdigit() for char in password):
            if any(string.punctuation for char in password):
                if any(char.isalpha() for char in password):
                    if any(char.isupper() for char in password):
                        if any(char.islower() for char in password):
                            return True
    return False

我知道它可以做得更好!它需要测试以下...

如果密码足够强 至少有 10 个字符 至少包含一位数字 至少包含一个大写字母 至少包含一个小写字母。密码只能包含 ASCII 拉丁字母或数字,但没有标点符号。

编辑

其他任何人都可以,我使用正则表达式将其归结为以下内容。

import re
def golf(password):
    return re.match( r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.{10,30}).+$', password)

显然它还可以更短......

【问题讨论】:

  • 你不能用and吗?
  • if any(string.punctuation for char in password): 看起来不对
  • 你考虑过正则表达式匹配吗?
  • 我知道这可能只是一个练习,但如果你真的在使用它来保护人们的安全,请考虑使用像 zxcvbn 这样的库。这是他们在 DropBox 使用的。甚至还有一个 Python 端口 github.com/dwolfhub/zxcvbn-python。它是专门为箔饼干而设计的,这很困难。
  • 如果你想走@DavidHoelzer 提到的正则表达式路线:stackoverflow.com/q/1559751/4996248

标签: python


【解决方案1】:

实际上,您已经很接近了。是的,您需要检查各种条件;规则复杂的。请注意,您不必检查alpha:对islowerisupper 的检查涵盖了这一点。您可以通过将规则放入单个表达式中来使这更容易处理:

import string
def golf(password):
    return \
        len(password) >= 10                              and \
        any(char.isdigit() for char in password)         and \
        not any(string.punctuation for char in password) and \
        any(char.isupper() for char in password)         and \
        any(char.islower() for char in password)

请注意,您正在评估一个布尔表达式:只需返回该值。不用说了

if <expr>:
    return True
else:
    return False

你已经拥有手头的价值;直接退货吧。

【讨论】:

  • 我觉得应该是all(char not in string.punctuation
  • 这个答案很有用,谢谢!我仍然认为它可以做得更短。也许是正则表达式?
  • 是的——正如您所发现的,您可以使用正则表达式使其更短。 “更好”是一种价值判断。我写这篇文章只是为了改进您现有的方法,保持简单性和可读性。
【解决方案2】:

这是一长串 if 语句 XD。你应该只使用一些和语句。

if len(password) >= 10 and any(char.isdigit() for char in password)...:
    return True
else:
    return False

如您所知,else 语句不是必需的,但它使代码更具可读性。

【讨论】:

  • 谢谢你,是的,如果你使用 and 语句,它会缩短,但也更难阅读,我相信它可以更容易阅读和更短。
【解决方案3】:

更理想的方法是在一个循环中完成所有字符检查。

import string
def golf(password):
    if len(password) < 10:
      return False

    saw_digit = saw_upper = saw_lower = False
    no_punct = all_alnum = True

    for char in password:
      saw_digit = saw_digit or char.isdigit()
      saw_upper = saw_upper or char.isupper()
      saw_lower = saw_lower or char.islower()
      no_punct = no_punct and (char not in string.punctuation)
      all_alnum = all_alnum and char.isalnum()

    values = [saw_digit, saw_lower, saw_upper, no_punct, all_alnum]
    # print(values)
    return all(values)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 1970-01-01
    • 2011-02-28
    • 2013-06-26
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多