[英]Writing code to check if a password meets certain criteria
I am trying to write a function in Python that checks a password and returns True or False based on the following criteria:我正在尝试在 Python 中编写一个 function 来检查密码并根据以下标准返回 True 或 False:
I have been trying to come up with code for a week now and have tried different variations of the following:我已经尝试了一周的代码,并尝试了以下不同的变体:
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
But the code does not work as intended because if there are, for example, only lower case letters it returns True.但是代码不能按预期工作,因为例如,如果只有小写字母,它会返回 True。 So I tried the following:
所以我尝试了以下方法:
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
But it doesn't return False when an invalid character is used (eg ~).但是当使用无效字符(例如~)时,它不会返回 False。 The function calls below should return True, True, False, False, False, True, False and 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'))
I will be most grateful if anyone points me in the right direction.如果有人指出我正确的方向,我将不胜感激。
The issue here is that on the occasion that any rule is true, it returns true.这里的问题是,在任何规则为真的情况下,它都会返回真。 But what you want is for it to check that all rules are true.
但是您想要的是它检查所有规则是否正确。 To do this, we'll need to make four different variables, one for each condition:
为此,我们需要创建四个不同的变量,每个条件一个:
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
I tested this and it gave me these results:我对此进行了测试,它给了我以下结果:
True
True
False
False
False
True
False
False
Note the last line there,注意最后一行,
return hs and hn and hu and hl
This is basically shorthand for saying this:这基本上是这样说的简写:
if not hs:
return False
if not hn:
return False
if not hu:
return False
if not hl:
return False
return True
By the way, this is a really useful password checker, might come in handy one day!顺便说一句,这是一个非常有用的密码检查器,也许有一天会派上用场!
Without steering you towards a rewrite (which IS a good idea) but only answering your direct question...无需引导您进行重写(这是一个好主意),而仅回答您的直接问题...
You are not checking for "the twist", the case where the password contains an invalid character.您没有检查“扭曲”,即密码包含无效字符的情况。 To do that, you need to add one more test to your conditional:
为此,您需要在条件中再添加一项测试:
and all((i.isupper() or i.islower() or i.isdigit() or i in list) for i in str)
which says that ALL characters in the password must be in one of the valid ranges of characters.这表示密码中的所有字符都必须在有效的字符范围之一内。 If you add this, you get the output you desire.
如果你添加这个,你会得到你想要的 output。
The full solution, including another minor fix, looks like this then:完整的解决方案,包括另一个小修复,如下所示:
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
and produces:并产生:
True
True
False
False
False
True
False
False
You can use this code, it also tells you why the password is incorrect.您可以使用此代码,它还会告诉您密码不正确的原因。 Simple if and else conditions.
简单的 if 和 else 条件。 But I would prefer if you use RegEx Python
但如果你使用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
Firt off, please don't define a variable called list
(or int
or str
for that matter) as this is a reserved word and a built-in function.首先,请不要定义名为
list
(或int
或str
)的变量,因为这是保留字和内置 function。 Then, you don't need a nested if-block but just a boolean value that gets set to False
if any of the conditions is not met.然后,您不需要嵌套的 if 块,只需要一个 boolean 值,如果不满足任何条件,该值将设置为
False
。 You can check the conditions independently:您可以独立检查条件:
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
By checking each condition subsequently, you don't have to nest your conditions and can detect the exact problem of the password.通过随后检查每个条件,您不必嵌套条件并且可以检测密码的确切问题。 You don't need to print them, of course, but this might help in debugging and testing for specific violations.
当然,您不需要打印它们,但这可能有助于调试和测试特定的违规行为。
Try this:尝试这个:
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())
I feel validating each condition step by step is a better approach to avoid confusions.我觉得逐步验证每个条件是避免混淆的更好方法。 This way we can let the user know what mistake they are committing to correct, rather than to just say if a password is valid or not.
通过这种方式,我们可以让用户知道他们正在纠正什么错误,而不仅仅是说密码是否有效。 Checking the password length and disallowed punctuation will be better ones to start validation.
检查密码长度和不允许的标点符号将更好地开始验证。
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
Test Cases测试用例
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'))
Result结果
True True False False False True False False
真 真 假 假 假 真 假 假
I have updated my answer and made it a bit simpler for you to understand.我已经更新了我的答案,让你更容易理解。 Let me know if this is easier to follow through.
让我知道这是否更容易完成。 The whole program loops through the string only once while checking for everything needed.
整个程序只在字符串中循环一次,同时检查所有需要的东西。 That way you don't have looping thru many times.
这样你就不会循环多次。
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')
The output for this will be as follows. output 如下。 I ran it multiple times:
我多次运行它:
Password :thisisnotagoodpassword
Invalid Password
Password :thisis notaG00dPassw0#d
Invalid Password
Password :thisisaG00dPassw0$d
Valid Password
Password :Abcd123$
Valid Password
Password :Abc123$
Invalid Password
How to convert this to a Function:如何将其转换为 Function:
You can always replace the print statement with a return True or return False statement when you convert this code into a function.当您将此代码转换为 function 时,您始终可以将 print 语句替换为 return True 或 return False 语句。 Then use the def to create.
然后使用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')
To call the function, you can do:要调用 function,您可以:
check = pword(input('Password. :'))
That will return the value of True
or False
to check.这将返回
True
或False
的值进行检查。
Hopefully it was helpful for you to understand the implementation.希望对您理解实现有所帮助。
I think using regular expression library "re" is the best way of doing this.我认为使用正则表达式库“re”是最好的方法。 so simple, so clean.
如此简单,如此干净。
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.