簡體   English   中英

編寫代碼以檢查密碼是否符合特定條件

[英]Writing code to check if a password meets certain criteria

我正在嘗試在 Python 中編寫一個 function 來檢查密碼並根據以下標准返回 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。 下面的 function 調用應返回 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'))

如果有人指出我正確的方向,我將不勝感激。

這里的問題是,在任何規則為真的情況下,它都會返回真。 但是您想要的是它檢查所有規則是否正確。 為此,我們需要創建四個不同的變量,每個條件一個:

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

順便說一句,這是一個非常有用的密碼檢查器,也許有一天會派上用場!

無需引導您進行重寫(這是一個好主意),而僅回答您的直接問題...

您沒有檢查“扭曲”,即密碼包含無效字符的情況。 為此,您需要在條件中再添加一項測試:

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

這表示密碼中的所有字符都必須在有效的字符范圍之一內。 如果你添加這個,你會得到你想要的 output。

完整的解決方案,包括另一個小修復,如下所示:

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

您可以使用此代碼,它還會告訴您密碼不正確的原因。 簡單的 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

首先,請不要定義名為list (或intstr )的變量,因為這是保留字和內置 function。 然后,您不需要嵌套的 if 塊,只需要一個 boolean 值,如果不滿足任何條件,該值將設置為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

通過隨后檢查每個條件,您不必嵌套條件並且可以檢測密碼的確切問題。 當然,您不需要打印它們,但這可能有助於調試和測試特定的違規行為。

嘗試這個:

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()) 

我覺得逐步驗證每個條件是避免混淆的更好方法。 通過這種方式,我們可以讓用戶知道他們正在糾正什么錯誤,而不僅僅是說密碼是否有效。 檢查密碼長度和不允許的標點符號將更好地開始驗證。

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'))

結果

真 真 假 假 假 真 假 假

我已經更新了我的答案,讓你更容易理解。 讓我知道這是否更容易完成。 整個程序只在字符串中循環一次,同時檢查所有需要的東西。 這樣你就不會循環多次。

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')

output 如下。 我多次運行它:

Password :thisisnotagoodpassword
Invalid Password

Password :thisis notaG00dPassw0#d
Invalid Password

Password :thisisaG00dPassw0$d
Valid Password

Password :Abcd123$
Valid Password

Password :Abc123$
Invalid Password

如何將其轉換為 Function:

當您將此代碼轉換為 function 時,您始終可以將 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')

要調用 function,您可以:

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

這將返回TrueFalse的值進行檢查。

希望對您理解實現有所幫助。

我認為使用正則表達式庫“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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM