2015-06-03 196 views
2

我需要一些幫助,弄清楚如何使一個函數檢查一串條件的字符串。Python密碼檢查器

  • 密碼必須長至少5個字符

  • 密碼必須包含至少一個大寫字母

  • 密碼必須包含至少兩個數字

  • 密碼不能包含字符「E」或「e」

  • 密碼必須包含t個最低一個特殊符號:!,@,#,$,%,^,&

現在這一切,我有

def passwordChecker(password): 
    ''' 
    ''' 
    caps = sum(1 for c in password if c.isupper()) 
    nums = sum(1 for c in password if c.isdigit()) 
    symb = any(c in password for c in '[email protected]#$%^&') 
    note = any(c in password for c in 'Ee') 
    if len(password) <5: 
     return False 
    elif caps < 1: 
     return False 
    elif nums < 1: 
     return False 
    elif symb == False: 
     return False 
    else: 
     return True 

編輯**

剛剛意識到我還必須檢查是否有常用的密碼,如'密碼'或'111111',我真的不知道我會如何處理這個問題。

import re 
def passwordChecker(password): 
    return all(re.search(pattern, password) for pattern in 
       ('.{5}', '[A-Z]', '\d.*\d', '^[^Ee]*$', '[[email protected]#$%^&]')) 

使用五個幾乎無效,五個幾乎沒有有效的測試演示(之一:

+1

您忘記檢查'note == False' –

+0

而'nums'應該是'nums <2'而不是 –

+0

您需要確定哪些值有資格作爲常用密碼,然後檢查它們。 – TigerhawkT3

回答

1

您使用正則表達式只是缺少一個分支

elif note: 
    return False 

else:

+0

我總是得到一個虛假的回報,這是我無法弄清的 –

+1

我嘗試了你的原始代碼以及這個加法,並且我並不總是會得到'False'。也許你沒有選擇一個可接受的密碼? – TigerhawkT3

2

只是一個替代之前無效,一個有效的五個規則):

for password in ('1A!', '12!34', 'A1bc!', 'A12E!', 'A12bc', 
       '1A!2.', 'A2!34', 'A12c!', 'A12b!', '[email protected]'): 
    print(passwordChecker(password)) 

打印False前五個和True爲最後五個。

0

以下內容將檢查每個故障情況並進行短路(一旦發現故障,它將停止檢查)。 「通用」密碼並不常見,但我想要的值可以通過其餘的檢查。

def passwordChecker(password): 
    ''' 
    A password checker. Returns True if the password is acceptable; False otherwise. 
    ''' 
    if (len(password) < 5 or 
     not any(c.isupper() for c in password) or 
     sum(c.isdigit() for c in password) < 2 or 
     'e' in password.lower() or 
     not (set(password) & set('[email protected]#$%^&')) or 
     password in {'Password12!', 'Passwd12!'}): 
     return False 
    return True 

>>> passwordChecker('Password12!') 
False 
>>> passwordChecker('hi') 
False 
>>> passwordChecker('H12!') 
False 
>>> passwordChecker('Hi12!') 
True 
1

這是談裝修的好時機!我使用裝飾器驗證數據,probably too much。你可以爲所有這些做驗證器,並將其包裝在你的方法get_password中。

def v_length(password): 
    return len(password) >= 5 
def v_upper(password): 
    return password.lower() != password 
def v_2_nums(password): 
    return sum(c.isdigit() for c in password) >= 2 
def v_no_e(password): 
    return "e" not in password.lower() 
def v_specialchar(password): 
    any(s in password for s in "[email protected]#$%^&") 

def validator(*tests): 
    def wrap(func): 
     def wrapped(*args, **kwargs): 
      result = func(*args, **kwargs) 
      if not all(test(result) for test in tests): 
       # fail the input somehow -- how?? 
      return result 
     return wrapped 
    return wrap 

@validator(v_length, v_upper, v_2_nums, v_no_e, v_specialchar) 
def get_password(): 
    pwd = input("Enter your password: ") 

我想換我的驗證在自己的工廠我這樣做的真正的代碼的時候,所以,它更容易根據應用

def v_length(min_length): 
    def wrapped(password): 
     return len(password) >= min_length 
    return wrapped 

@validator(v_length(8)) 
def get_weak_password(): 
    input("Enter your wussy password: ") 

@validator(v_length(64)) 
def get_strong_password(): 
    input("Enter your Herculean password: ") 

這第二種方法可以很好地用於檢查常見的密碼更改。

def v_common(common_pwd_set): 
    def wrapped(password): 
     return password not in common_pwd_set 
    return wrapped 

COMMON_PASSWORDS = {"hunter2", "111111", "password"} 
@validator(v_common(COMMON_PASSWORDS)) 
def get_password(): 
    pwd = input("Use a tricksy one! ") 
0

另一種方式來做到這一點...

def passwordChecker(password): 
    return (len(password) > 4 and 
      len(filter(str.isupper, password)) > 0 and 
      len(filter(str.isdigit, password)) > 1 and 
      'e' not in password.lower() and 
      any(special in password for special in '[email protected]#$%^&') and 
      password not in ('password', '111111')) 

我覺得我的解決方案中最有趣的部分是使用filter;有些人喜歡它,有些則討厭它。無論如何,所有其他解決方案的工作也是如此。只是以爲我會把這個完整的混合在一起。