【问题标题】:How to check if string has lowercase letter, uppercase letter and number [duplicate]如何检查字符串是否有小写字母,大写字母和数字[重复]
【发布时间】:2018-02-03 07:44:20
【问题描述】:

我需要做一个简单的密码检查器,它需要检查字符串是否至少有一个小写字母、一个大写字母和一个数字。

这就是我所拥有的

passwd = raw_input("enter your password: ")
upper = 0
lower = 0 
number = 0
while len(passwd) < 7 and upper <= 0 and lower <= 0 and number <= 0:
    print 'start'
    for x in passwd:
        if x.isupper()==True:
            print 'upper'
            upper+=1
        elif x.islower()==True:
            print 'lower'
            lower+=1
        elif x.isalpha()==False:
            print 'num'
            number+=1
    print ('password not complex enough')
    upper = 0
    lower = 0
    number = 0
    passwd = raw_input('please enter password again ')

那些看起来随机的打印是为了调试,所以我可以看到它到达的位置。

看起来正在发生的是它只检查第一个条件,长度条件,然后离开循环。

这是正在发生的事情的示例

enter your password: pA1
start
lower
upper
num
password not complex enough
please enter password again password

为什么只检查长度条件?我做错了什么?

【问题讨论】:

  • “为什么只检查长度条件?” - 是什么让你认为它只是这样做?您在输出中得到loweruppernum - 如果不是这些条件,您认为这是从哪里来的?你只会得到password not complex enough,因为你每次都会输出那个,完全独立于你的实际条件检查结果。
  • elif 更改为if
  • while 循环的条件是 True 仅在第一个循环中,因为一旦上限、下限或数字得到&lt; 0,它将评估为False,因为你是使用and
  • @CBroe 我不认为它只是这样做,我的意思是它只使用该条件离开循环,如果字符串长于 7 则它离开循环而不检查是否有大写或小写字母
  • 嗯,当然,因为您将len(passwd) &lt; 7 设置为决定它是否进入循环体的条件之一......

标签: python


【解决方案1】:

您可以通过使用unicodedata.category 来收集字符的类别,然后检查是否所有预期都存在,从而简化整个逻辑,例如:

import unicodedata

is_valid = (
    len(password) >= 7 and 
    {'Ll', 'Lu', 'Nd'}.issubset(unicodedata.category(ch) for ch in password)
)

【讨论】:

  • 非常好。虽然我更喜欢{'Ll', 'Lu', 'Nd'} &lt;= set(map(unicodedata.category, password)){'Ll', 'Lu', 'Nd'}.issubset(map(unicodedata.category, password))
  • @Stefan 选择 .issubset 以允许它接受任何可迭代并避免显式创建 set 和 gen-comp 而不是 map 以保持其功能相同Py 2 和 Py3...(避免在 Py 2 中构建不必要的 list)...但是是的...它们都可以工作...
  • 嗯,好的,虽然只要一个密码的列表可能不是那么浪费:-)
  • @Stefan 一个非常公平的观点 :)
  • 我想以最简单和最易读的方式来做这件事,这对我来说似乎是正确的。我正在考虑使用正则表达式来简化它,但你的方式很棒
【解决方案2】:

您的检查逻辑有问题。首先,在while 条件可以检查它们之前重新设置控制变量。此外,您使用and 来测试所有条件是否为真,而or 是您应该使用的。如果要保留代码的基本结构,最好的方法是在 while 语句中仅使用 True,然后在满足所有条件后使用 break 循环。当然,如其他答案所示,还有更紧凑的方法来检查是否满足所有条件。

passwd = raw_input("enter your password: ")
upper = 0
lower = 0 
number = 0
while True:
    for x in passwd:
        if x.isupper()==True:
            print 'upper'
            upper+=1
        elif x.islower()==True:
            print 'lower'
            lower+=1
        elif x.isalpha()==False:
            print 'num'
            number+=1
    if len(passwd) < 7 or upper <= 0 or lower <= 0 or number <= 0:
        print ('password not complex enough')
        passwd = raw_input('please enter password again ')
        upper = 0
        lower = 0
        number = 0
    else:
        break



print 'final password:', passwd

输出:

enter your password: pA
lower
upper
password not complex enough
please enter password again pA1ghlfx78
lower
upper
num
lower
lower
lower
lower
lower
num
num
final password: pA1ghlfx78

【讨论】:

  • 谢谢!我知道有更好的方法和更有效的方法来做到这一点,我想到的是使用正则表达式,但想让它尽可能简单易读,我认为这是最好的方法
【解决方案3】:

如果密码必须仅包含 ASCII 字母和数字,那么最有效的方法是使用sets

from string import ascii_lowercase, ascii_uppercase, digits

def is_valid(password):
    if len(password) < 7:
        return False
    password_set = set(password)
    return not any(password_set.isdisjoint(x)
                   for x in (ascii_lowercase, ascii_uppercase, digits))

如果允许使用 unicode 字符,您可以使用 any():

 def is_valid(password):
     return (len(password) >= 7 and
             any(c.islower() for c in password) and
             any(c.isupper() for c in password) and
             any(c.isdigit() for c in password))

【讨论】:

    【解决方案4】:

    希望这对你有帮助。我使用sum(1 for c in the string if c.islower()) 来查找小写字母的总数。以及查找大写和数字的总数的相同方法。len(string) 查找字符串的长度。

    string=input()
    if ((sum(1 for c in string if c.islower())>=1) and (sum(1 for c in string if 
    c.isupper())>=1) and (sum(1 for c in string if c.isdigit())>=1) and (len(string)>=7)):
        print("Password is complex")
    else:
        print ("Password not complex enough")
    

    【讨论】:

    • 为什么要投入?答案有问题吗?
    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2021-08-12
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多