1

我正在尝试在 Python 中编写一个函数来检查密码并根据以下条件返回 True 或 False:

  • 它必须至少有 8 个字符长
  • 它必须至少包含一个大写字母
  • 它必须包含至少一个小写字母
  • 它必须包含至少一个数字
  • 它必须至少包含以下特殊字符之一:!@#$%&()-_[]{};':",./<>?列出,例如空格、~ 或 * 或其他任何内容。

我已经尝试了一周的代码,并尝试了以下不同的变体:

def password_check(str):
    list = ['!', '@', '#', '$', '%', '&', '(', ')', '-', '_', '[', ']', '{', '}', ';', ':', '"', '.', '/', '<', '>', '?']
    estr = True
    if len(str) >= 8:
        for i in str:
            if i in list:
                estr = True
            else:
                if i.isnumeric():
                    estr = True
                else:
                    if i.isupper():
                        estr = True
                    else:
                        if i.islower():
                            estr = True
                        else:
                            return False
    else:
        estr = False
    return estr

但是代码不能按预期工作,因为例如,如果只有小写字母,它会返回 True。所以我尝试了以下方法:

def password_check(str):
    list = ['!', '@', '#', '$', '%', '&', '(', ')', '-', '_', '[', ']', '{', '}', ';', ':', '"', '.', '/', '<', '>', '?']
    if any(i.isupper() for i in str) and any(i.islower() for i in str) and any(i.isdigit() for i in str) and len(str) >= 8 and any(i in list for i in str):
        estr = True
    else:
        return False

但是当使用无效字符(例如~)时,它不会返回 False。下面的函数调用应返回 True、True、False、False、False、True、False 和 False。

print(password_check("tHIs1sag00d.p4ssw0rd."))
print(password_check("3@t7ENZ((T"))
print(password_check("2.shOrt"))
print(password_check("all.l0wer.case"))
print(password_check("inv4l1d CH4R4CTERS~"))
print(password_check('X)ndC@[?/fVkoN/[AkmA0'))
print(password_check(':>&BhEjGNcaSWotpAy@$tJ@j{*W8'))
print(password_check('ZW}VoVH.~VGz,D?()l0'))

如果有人指出我正确的方向,我将不胜感激。

4

8 回答 8

2

这里的问题是,在任何规则为真的情况下,它都会返回真。但是您想要的是它检查所有规则是否正确。为此,我们需要创建四个不同的变量,每个条件一个:

def password_check(str):
    list = ['!', '@', '#', '$', '%', '&', '(', ')', '-', '_', '[', ']', '{', '}', ';', ':', '"', '.', '/', '<', '>', '?']
    hs = False # Has Symbols
    hn = False # Has Numbers
    hu = False # Has Uppercase
    hl = False # Has Lowercase
    if len(str) >= 8:
        for i in str:
            if i in list:
                hs = True
            elif i.isnumeric():
                hn = True
            elif i.isupper():
                hu = True
            elif i.islower():
                hl = True
            else:
                return False
    else:
        return False
    return hs and hn and hu and hl

我对此进行了测试,它给了我以下结果:

True
True
False
False
False
True
False
False

注意最后一行,

return hs and hn and hu and hl

这基本上是这样说的简写:

if not hs:
    return False
if not hn:
    return False
if not hu:
    return False
if not hl:
    return False
return True

顺便说一句,这是一个非常有用的密码检查器,也许有一天会派上用场!

于 2020-08-19T05:59:04.263 回答
1

无需引导您进行重写(这是一个好主意),而仅回答您的直接问题...

您没有检查“扭曲”,即密码包含无效字符的情况。为此,您需要在条件中再添加一项测试:

and all((i.isupper() or i.islower() or i.isdigit() or i in list) for i in str)

这表示密码中的所有字符都必须在有效的字符范围之一内。如果你添加它,你会得到你想要的输出。

完整的解决方案,包括另一个小修复,如下所示:

def password_check(str):
    list = ['!', '@', '#', '$', '%', '&', '(', ')', '-', '_', '[', ']', '{', '}', ';', ':', '"', '.', '/', '<', '>',
            '?']
    if any(i.isupper() for i in str) and any(i.islower() for i in str) and any(i.isdigit() for i in str) and len(
            str) >= 8 and any(i in list for i in str) and all((i.isupper() or i.islower() or i.isdigit() or i in list) for i in str):
        return True
    else:
        return False

并产生:

True
True
False
False
False
True
False
False
于 2020-08-19T05:55:00.997 回答
1

您可以使用此代码,它还会告诉您密码不正确的原因。简单的 if 和 else 条件。但如果你使用RegEx Python ,我会更喜欢

def password_check(password):

    SpecialSym = ['!', '@', '#', '$', '%', '&',
                  '(', ')', '-', '_', '[', ']', '{', '}', ';', ':', '"', '.', '/', '<', '>', '?']

    if len(password) < 8:
        print('length should be at least 6')
        return False

    if not any(char.isdigit() for char in password):
        print('Password should have at least one numeral')
        return False

    if not any(char.isupper() for char in password):
        print('Password should have at least one uppercase letter')
        return False

    if not any(char.islower() for char in password):
        print('Password should have at least one lowercase letter')
        return False

    if not any(char in SpecialSym for char in password):
        print('Password should have at least one of the symbols $@#')
        return False

    for i in password:
        if not (('0' <= i <= '9') or ('a' <= i.lower() <= 'z')):
            # Special Char
            if i not in SpecialSym:
                return False

    return True
于 2020-08-19T05:59:54.513 回答
0

尝试这个 :

import string 
sc = "!@#$%&()-_[]{};:,./<>?"
uc = string.ascii_uppercase
lc = uc.lower()
num = string.digits

def password_checker(password):
     if len(password) >= 8:
       sn = 0 #numbers of special character
       un = 0 #......... uppercase letters
       ln = 0 #........ lowercase 
       dn = 0 #.........digits
       for i in password:
           if i in uc:
              un += 1
           elif i in lc:
              ln += 1
           elif i in num:
             dn += 1
           elif i in sc and sn == 0:
             sn += 1
           else:
             break
       else:
             print("Valid Password")
     else:
        print("Invalid Password")   



password_checker(input()) 
于 2020-08-19T06:03:06.740 回答
0

我觉得逐步验证每个条件是避免混淆的更好方法。通过这种方式,我们可以让用户知道他们正在纠正什么错误,而不仅仅是说密码是否有效。检查密码长度和不允许的标点符号将更好地开始验证。

import re


def password_check(password):
    return_value = True

    if len(password) < 8:
        # print('Password length is less than 8 characters')
        return_value = False

    punctuation_not_allowed = '[\s+*+=\^`|~]'
    if re.search(punctuation_not_allowed, password):
        # print(f'Whitespaces or punctuations "*+=\^`|~" is not allowed')
        return_value = False

    if not any(char.isupper() for char in password) or \
            not any(char.islower() for char in password) or \
            not any(char.isdigit() for char in password):
        # print('Password requires at least one upper case letter, one lower case letter and one digit')
        return_value = False

    if not re.search(r"""[!@#$%&()\-_\[\]{};':",./<>?]""", password):
        # print("""At least special char in "[!@#$%&()-_[]{};':",./<>?]" is required""")
        return_value = False

    return return_value

测试用例

print(password_check("tHIs1sag00d.p4ssw0rd."))
print(password_check("3@t7ENZ((T"))
print(password_check("2.shOrt"))
print(password_check("all.l0wer.case"))
print(password_check("inv4l1d CH4R4CTERS~"))
print(password_check('X)ndC@[?/fVkoN/[AkmA0'))
print(password_check(':>&BhEjGNcaSWotpAy@$tJ@j{*W8'))
print(password_check('ZW}VoVH.~VGz,D?()l0'))

结果

真 真 假 假 假 真 假 假

于 2020-08-19T06:50:50.437 回答
0

首先,请不要定义一个名为list(或intstr就此而言)的变量,因为这是一个保留字和一个内置函数。然后,您不需要嵌套的 if 块,而只需要一个布尔值,False如果不满足任何条件则设置为。您可以独立检查条件:


def password_check(p):
    print('\nchecking password: ',p)
    chlist = ['!', '@', '#', '$', '%', '&', '(', ')', '-', '_', '[', ']', '{', '}', ';', ':', '"', '.', '/', '<', '>', '?']
    good_password = True ## Set to true and try to disprove

    nums = False
    letters = False
    special = False

    for c in p:
        if not (c.isalnum() or c in chlist):
            good_password = False
            print("Invalid character: "+c)
        elif c.isdigit():
            nums = True
        elif c.isalpha():
            letters = True
        elif c in chlist:
            special = True
    if not letters:
        good_password = False
        print("There are no letters")
    if not nums:
        good_password = False
        print("There are no numbers")
    if not special:
        good_password = False
        print("There are no special characters")
    if p == p.lower() or p==p.upper():
        good_password = False
        print("Please use upper and lower case letters")
    if len(p) < 8:
        good_password = False
        print("Too short")

    return good_password

通过随后检查每个条件,您不必嵌套条件并且可以检测密码的确切问题。当然,您不需要打印它们,但这可能有助于调试和测试特定的违规行为。

于 2020-08-19T05:55:51.050 回答
0

我已经更新了我的答案,让你更容易理解。让我知道这是否更容易完成。整个程序只在字符串中循环一次,同时检查所有需要的东西。这样你就不会循环多次。

pwd = input('Password :')

#set uppercase, lowercase, digits, special to False
#if password has these, then set to True

ucase = lcase = digit = scase = False

#for loop when applied to a string will pick each char for processing
#this will allow you to  check for conditions on the char

for ch in pwd:

    #check if char is uppercase, set ucase to True

    if ch.isupper(): ucase = True

    #check if char is lowercase, set lcase to True

    elif ch.islower(): lcase = True

    #check if char is a number, set digit to True

    elif ch.isdigit(): digit = True

    #check if char is special char, set scase to True
    #by using in (...), it checks against each item in the list

    elif ch in ('!@#$%&()-_[]{};\':",./<>?'): scase = True

    #if it is not one of these, then it is not valid password
    else:
        break

#check if everything is true

if len(pwd) >= 8 and ucase and lcase and digit and scase:
    print ('Valid Password')
else:
    print ('Invalid Password')

输出如下。我多次运行它:

Password :thisisnotagoodpassword
Invalid Password

Password :thisis notaG00dPassw0#d
Invalid Password

Password :thisisaG00dPassw0$d
Valid Password

Password :Abcd123$
Valid Password

Password :Abc123$
Invalid Password

如何将其转换为函数:

当您将此代码转换为函数时,您始终可以将 print 语句替换为 return True 或 return False 语句。然后使用def创建。

def pword(pwd):
    #the whole code from #set uppercase... (except first line)
    #to the final if statement
    #if you want to return True or False, you can use
    #return True instead of print ('Valid Password')

要调用该函数,您可以执行以下操作:

check = pword(input('Password. :'))

这将返回TrueFalse检查的值。

希望对您理解实现有所帮助。

于 2020-08-19T08:06:18.480 回答
0

我认为使用正则表达式库“re”是最好的方法。如此简单,如此干净。

import re

while True:
    p = input('enter a new password: ')
    if (len(p) < 6 or len(p)>16):
        print('Your password should be between 6-16 characters.')
    
    elif not re.search("[A-Z]", p):
        print('Your password should include at least one capital letter.')
        
    elif not re.search('[a-z]', p):
        print('Your password should include at least one letter.')

    elif not re.search('[0-9]', p):
        print('Your password should include at least one number.')

    elif not re.search('[@#$%]', p):
        print('Your password should include at least one of these signs: @#$%')
    
    else:
        print('Your password is valid.')
        break
于 2021-12-26T16:30:13.590 回答