I am trying to write a function in Python that checks a password and returns True or False based on the following criteria:
- it must be at least 8 characters long
- it must contain at least one capital letter
- it must contain at least one lower case letter
- it must contain at least one number
- it must contain at least one of the following special characters: !@#$%&()-_[]{};':",./<>? The twist is that it MUST NOT contain special characters other than the ones listed, e.g. a space, ~ or * or anything else.
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. 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 (e.g. ~). The function calls below should return True, True, False, False, False, True, False and 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.
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:
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.
The full solution, including another minor fix, looks like this then:
and produces: