I am working on an assignment for password validation where the program keeps asking the user for a valid password until one is given. I am having trouble checking the input string for special characters. Currently the program accepts the password even if their is no special characters. Also I would like to implement a feature that terminates the loop after 3 unsuccessful attempts but am not sure which loop to implement the count in.
Here is my code:
import re
specialCharacters = ['$', '#', '#', '!', '*']
def passwordValidation():
while True:
password = input("Please enter a password: ")
if len(password) < 6:
print("Your password must be at least 6 characters.")
elif re.search('[0-9]',password) is None:
print("Your password must have at least 1 number")
elif re.search('[A-Z]',password) is None:
print("Your password must have at least 1 uppercase letter.")
elif re.search('specialCharacters',password) is None:
print("Your password must have at least 1 special character ($, #, #, !, *)")
else:
print("Congratulations! Your password is valid.")
break
passwordValidation()
There is no need to use regular expression for something so simple. How about:
elif not any(c in specialCharacters for c in password):
or
specialCharacters = set('$##!*')
...
elif not specialCharacters.intersection(password):
Related
This question already has answers here:
How do Python's any and all functions work?
(10 answers)
Closed 5 months ago.
I want to create a password program that checks to see if a special character is inside an input.
So I created a list with some special characters so that if just one or multiple symbols are detected in the input, then it should do something:
SpecialSymbols =['$', '#', '#', '%']
Password = input("type password")
if Password in SpecialSymbols:
print("strong password")
else:
print("no special character detected")
I think I need to use a for loop as well in which case it prints all items. Or I may need to check just specific characters and not the entire input, how do I do this?
You can use any (if there should be at least one special char from the list) or all if there must be all special chars from the list in the input string.
if any(x in SpecialSymbols for x in Password):
if all(x in SpecialSymbols for x in Password):
See a Python demo:
SpecialSymbols =['$', '#', '#', '%']
Passwords = ["String #$%#", "String #1", "String"]
for Password in Passwords:
if any(x in SpecialSymbols for x in Password):
print("strong password")
else:
print("no special character detected")
Output for this snippet:
strong password
strong password
no special character detected
Loop through the string
SpecialSymbols =['$', '#', '#', '%']
Password = input("type password")
strong = False
for c in Password:
if c in SpecialSymbols:
strong = True
break
if strong:
print("Password is strong")
else:
print('password is weak')
To solve your problem, I have created a function that is going to check for each letter in the word if it is a special character. If it is, then it is going to higher the score and return true. Then you can use this function for the input password.
Here is the code :
SpecialSymbols =['$', '#', '#', '%']
Password = input("type password")
def strongPassword(password):
score = 0
for letter in Password:
for spec in SpecialSymbols:
if letter == spec :
score = score + 1
print(score)
if score :
return True
strongPassword(Password)
if strongPassword(Password):
print("strong password")
else:
print("no special character detected")
This code detects how many of the special characters are in the password.
SpecialSymbols =['$', '#', '#', '%']
Password = input("type password")
number = 0
for symbol in SpecialSymbols: # for each symbol
if symbol in Password: # check if it is in the password
number += 1
if number >= 1: # symbol detected in the password
print("strong password (%d special symbols in)" % number)
else:
print("no special character detected")
More compact: only check if there is any symbol, not using a counter of occurrences but a boolean strong value:
strong = False
for symbol in SpecialSymbols:
if symbol in Password:
strong = True
break
if strong:
print("strong password")
else:
print("no special character detected")
I've been trying to figure this out my own, but I couldn't come up with solutions for this. I did come across to SpecialSym["$", "#", "#"] but I wasn't able to work that one into this code.
print("Password is incorrect, please try again...")
passW()
You can do this by adding the condition which would check whether any of the characters is in the list ["$", "#", "#"] or not.
The updated code would be:
import re #regular expression
print("Please enter a password to log in...")
def passW():
while True:
password=input("Enter a password:\n")
if password=="Y0urC0llege":
print("Logging in...")
print("Your login was successful.")
print("Welcome, Professor.")
break
elif len(password) < 10:
print("Please make sure your password is as least 10 characters long.")
elif re.search("[0-9]", password) is None:
print("Please contain as least 1 number in your password.")
elif re.search("[A-Z]", password) is None:
print("Please contain 1 capital letter in your password")
elif re.search("[$##]", password) is None:
print("Please contain as least 1 character symbol in your password.")
else:
print("Password is incorrect, please try again...")
passW()
Hope it helps.
You have to take special characters in a variable after that you can check the condition like below:
SpecialSym = ['!','#','#'] # You can add as many symbols you want.
elif not any(char in SpecialSym for char in password):
print("Please contain as least 1 character symbol in your password.")
The program, which assesses password strength, initially checks whether the length of the password is correct (6-12) and whether the password contains extented ASCII characters, i.e. 127-255.
The problem I have is that if the user first inputs a password which is too short or too long, the program then doesn't check for extended characters in the next password, inputted by the user and vice-versa, with checking for extended characters first.
I implemented a double while loop, if that's the correct way of calling it, however it still didn't bring the desired effect.
import re
import time
#score variable, responsible for later defining if passwords is weak, medium or strong
Score = 0
#list for improvements to password printed out with score at the end
Improvements = []
Password = ""
#defines function for checking for presence of extended characters (i.e. ascii 128-255)
def hasExtended(s):
return any(ord(i) > 127 for i in s)
#inputs password
Password = input("Please enter a password:")
Password_length = len(Password)
Extended_presence = hasExtended(Password)
#checks password length (6-12), asks user to re-input until password is within boundaries
#checks if password contains extended characters
#double while loops to allow for two conditions simultaneously
while Password_length < 6 or Password_length > 12:
if Password_length < 6:
Outputted_length = "too short"
Outputted_criteria = "no shorter than 6 characters"
else:
Outputted_length = "too long"
Outputted_criteria = "no longer than 12 characters"
print("Your password is", Outputted_length, ". It has to be", Outputted_criteria, ".")
Password = input("Please enter a password:")
Password_length = len(Password)
while Extended_presence:
print("Your password contains characters from the extended ASCII list. Please don't use these.")
Password = input("Please enter a password:")
Extended_presence = hasExtended(Password)
while Extended_presence:
print("Your password contains characters from the extended ASCII list. Please don't use these.")
Password = input("Please enter a password:")
Extended_presence = hasExtended(Password)
while Password_length < 6 or Password_length > 12:
if Password_length < 6:
Outputted_length = "too short"
Outputted_criteria = "no shorter than 6 characters"
else:
Outputted_length = "too long"
Outputted_criteria = "no longer than 12 characters"
print("Your password is", Outputted_length, ". It has to be", Outputted_criteria, ".")
Password = input("Please enter a password:")
Password_length = len(Password)
else:
#defines function for checking for presence of numbers
def hasNumbers(s):
return any(i.isdigit() for i in s)
#defines function for checking for presence of letters
def hasLetters(s):
return any(i.isalpha() for i in s)
#defines function for checking for presence of special characters
def hasSpecial(s):
return any(ord(i) < 48 for i in s)
#checks if password contains letters
Letter_presence = hasLetters(Password)
if not Letter_presence:
Score = Score - 1
Improvements.append("letters")
else:
Score = Score + 1
#checks if password is all upper case
Is_upper = Password.isupper()
if not Is_upper:
Score = Score + 1
else:
Score = Score - 1
Improvements.append("upper and lower case letters")
#checks if passwords is all lower case
Is_lower = Password.islower()
if not Is_lower:
Score = Score + 1
else:
Score = Score - 1
Improvements.append("upper and lower case letters")
#checks if password contains a number
Number_presence = hasNumbers(Password)
if not Number_presence:
Score = Score + 0
Improvements.append("numbers")
else:
Score = Score + 1
#checks if password is just numbers
Only_numbers = Password.isdigit()
if not Only_numbers:
Score = Score + 0
else:
Score = Score - 1
Improvements.append("other characters")
#checks if password contains special characters
Special_presence = hasSpecial(Password)
if not Special_presence:
Score = Score + 0
Improvements.append("special characters, such as '$'")
else:
Score = Score + 1
#outputs weak, medium or strong password to user and suggest improvements
if Score <= 2:
print("The program is processing your password...")
time.sleep(2)
print("Your password isn't acceptable! Please try again.")
print("Next time, remember to include", Improvements)
if Score == 3:
print("The program is processing your password...")
time.sleep(2)
print("Your password is weak, you should try again.")
print("Next time, remember to include", Improvements)
elif Score == 4:
print("The program is processing your password...")
time.sleep(2)
print("Your password is medium, it should be OK.")
print("Next time, remember to include", Improvements)
elif Score == 5:
print("The program is processing your password...")
time.sleep(2)
print("Your password is strong, it is absolutely fine.")
I would suggest you to write validator, a function that looks like this:
def validate_password(password):
... # check score, symbols and other, print whatever you want
return score
And then call it in a way like that one:
pass = input('Enter your password')
score = validate_password(pass)
while score <= 3:
pass = input('Enter another password')
score = validate_password(pass)
You can implement such scenario like below:
check_pass function will check for length of function
def hasExtended(s):
return any(ord(i) > 127 for i in s)
check_pass = lambda x: x>=6 and x<=12 # check for range of input value
password=input("Password: ")
if check_pass(len(password)) and not hasExtended(password):
print("Valid password")
else:
print("Do not use extended ascii characters, use password with minimum length of 6 and maximum length of 12")
to be more precise about error you can use nesting in below way:
if check_pass(len(password)) and not hasExtended(password):
print("Valid password")
elif check_pass(len(password)) and hasExtended(password):
print("do not use extended ascii character")
elif not check_pass(len(password)) and hasExtended(password):
print("password length should be between 6 to 12")
similarly if you want to check for invalid length of minimum lenght and maximum length separately.
If you wish to check all condition separately and then show success or failure you can do like below:
def verify_password(password):
if len(password) < 6:
print("require minimum 6 characters")
if len(password) > 12:
print("can not use more then 12 characters")
if hasExtended(password):
print("use only valid ascii characters")
else:
print("valid password")
return True
while not verify_password(password): # loop will never stops unless valid password or used break statement within
password = input("Password: ")
The function will check for three different condition if condition satisfied message will be printed else it will continue executing, at the end if it is valid password instead of printing anything it will print valid password and return True instead of None.
Try this code , and instead of while just use if in first checking codition of Extended_presence , You don't need while there because its already in the scope of previous while loop :
import re
print([chr(i) for i in range(127,200)])
import re
import time
#score variable, responsible for later defining if passwords is weak, medium or strong
Score = 0
#list for improvements to password printed out with score at the end
Improvements = []
Password = ""
#defines function for checking for presence of extended characters (i.e. ascii 128-255)
def hasExtended(s):
return any(ord(i) > 127 for i in s)
#inputs password
Password = input("Please enter a password:")
Password_length = len(Password)
Extended_presence = hasExtended(Password)
#checks password length (6-12), asks user to re-input until password is within boundaries
#checks if password contains extended characters
#double while loops to allow for two conditions simultaneously
while Password_length < 6 or Password_length > 12:
if Password_length < 6:
Outputted_length = "too short"
Outputted_criteria = "no shorter than 6 characters"
else:
Outputted_length = "too long"
Outputted_criteria = "no longer than 12 characters"
print("Your password is", Outputted_length, ". It has to be", Outputted_criteria, ".")
Password = input("Please enter a password:")
Password_length = len(Password)
if Extended_presence:
print("Your password contains characters from the extended ASCII list. Please don't use these.")
Password = input("Please enter a password:")
Extended_presence = hasExtended(Password)
while Extended_presence:
print("Your password contains characters from the extended ASCII list. Please don't use these.")
Password = input("Please enter a password:")
Extended_presence = hasExtended(Password)
output:
Please enter a password:hel¢
Your password is too short . It has to be no shorter than 6 characters .
Please enter a password:hello¢
Your password contains characters from the extended ASCII list. Please don't use these.
Please enter a password:hello¢
Your password contains characters from the extended ASCII list. Please don't use these.
Please enter a password:hellllo#
Why don't you delegate your password check to a function and separate the user input from checking the password? That way you can ask the user as many times as you want without complex jumps. Something like:
def validate_password(password):
if len(password) < 6:
return 0, "Your password is too short, it has to be no shorter than 6 characters."
elif len(password) > 12: # why, tho?
return 0, "Your password is too long, it has to be no longer than 12 characters."
# these can be optimized but I'll leave that as an exercise for you
if any(ord(i) > 127 for i in password): # again, why?!
return 0, ("Your password contains characters from the extended ASCII list. "
"Please don't use these.")
score = 0
improvements = []
if any(i.isalpha() for i in password):
score += 1
if password.isupper() or password.islower():
score -= 1
improvements.append("upper and lower case letters")
else:
score += 1
else:
score -= 1
improvements.append("letters")
if any(i.isdigit() for i in password):
score += 1
if password.isdigit():
score -= 1
improvements.append("other characters")
else:
# score -= 1 # are you sure you don't want to reduce the score?
improvements.append("numbers")
if any(ord(i) < 48 for i in password):
score += 1
else:
# score -= 1 # are you sure you don't want to reduce the score?
improvements.append("special characters such as '$'")
return score, "Next time remember to include: {}".format(", ".join(improvements))
And now you can call it from wherever you want, as many times as you need:
while True:
candidate = input("Please enter a password: ")
print("The program is processing your password...") # why? this happens in an instant
score, message = validate_password(candidate)
time.sleep(2) # why are we making people wait for no reason?
if score <= 1:
print(message)
print("Please try again.")
elif score == 2:
print("Your password is weak, you should try again.")
print(message)
elif score == 3:
print("Your password is medium, it should be OK.")
print(message)
break
elif score == 4:
print("Your password is strong, it is absolutely fine.")
break
print("Accepted password: " + candidate)
And you can get an output as:
Please enter a password: dfld
The program is processing your password...
Your password is too short, it has to be no shorter than 6 characters.
Please try again.
Please enter a password: dfldsadlslads
The program is processing your password...
Your password is too long, it has to be no longer than 12 characters.
Please try again.
Please enter a password: dflds°
The program is processing your password...
Your password contains characters from the extended ASCII list. Please don't use these.
Please try again.
Please enter a password: ddlllsd
The program is processing your password...
Next time remember to include: upper and lower case letters, numbers, special characters
such as '$'
Please try again.
Please enter a password: ddlllsd12
The program is processing your password...
Next time remember to include: upper and lower case letters, special characters such as '$'
Please try again.
Please enter a password: Ddlllsd12
The program is processing your password...
Your password is medium, it should be OK.
Next time remember to include: special characters such as '$'
Accepted password: Ddlllsd12
incorrectPassword= True
while incorrectPassword:
password = input("type in your password: ")
if len(password) < 8:
print("your password must be 8 characters long")
if len(password) >24:
print("Your password must be shorter than 24 characters")
elif not any(i.isdigit() for i in password):
print("you need a number in your password")
elif not any(i.isupper() for i in password):
print("you need a capital letter in your password")
elif not any(i.islower() for i in password):
print("you need a lowercase letter in your password")
incorrectPassword = False
How can I only allow certain characters (like !, $, %, ^, &, *, (, ), -, _, = or +) as needed input?
I would use regex, but to do it in a similar fashion to your other tests:
any(i not in '!$%^&*()-_=+' for i in password)
you can simply use
elif " " in password:
#print error
or use Python's re package to define what characters are allowed in your password
I have set up a program to change a "password". I have it checking to see if it is at least 8 characters, contains a capital letter and has a number, and if it does not meet this criteria, it asks for the password again. I have everything working except the checking for a number and I was wondering if someone could help.
npwv = 1
while npwv == 1:
npw = input("Please enter new password.")
npwc = input ("Please confirm new password")
if npwc == npw:
if npwc.isupper()== False:
if npwc.islower()== False:
if len(npwc) >= 8:
if str.isdigit(npwc) == True:
npw=npwc
print("Your password has been changed")
else:
print("Your password must contain a number")
npwv = 1
else:
print("Your password must contain at least 8 characters.")
npwv = 1
else:
print("Your password must contain at least 1 upper case character.")
npwv = 1
else:
print ("Passwords don't match")
npwv = 1
You are checking if the password itself is fully uppercase or composed of numbers. What you need to check if if the characters in the password match this criteria.
has_upper = any([c.isupper() for c in npwc])
has_digit = any([c.isdigit() for c in npwc])
You can also use regular expressions.
By the way, you should prefer getpass to get the password from the user.
Have you considered using .isalnum()?
>>> foo = "123asd"
>>> foo
'123asd'
>>> foo.isalnum()
True
>>>
Edit: Judging by the other answers, I am not sure what are you looking for, could explain it with examples?
I would suggest using sets, and the string package from stdlib for your list of acceptable characters.
I would also suggest refactoring a bit to remove a lot of the nesting with if / else branches.
import string
upper = set(list(string.uppercase))
lower = set(list(string.lowercase))
numbers = set(list(string.digits))
while True:
npw = input("Please enter new password: ")
npwc = input("Please confirm new password: ")
if npwc != npw:
print("Passwords don't match")
continue
if len(npcw) < 8:
print("Your password must contain at least 8 characters.")
continue
chars = set(list(npwc))
if not upper.intersection(chars):
print("Your password must contain at least 1 upper case character.")
continue
if not lower.intersection(chars):
print("Your password must contain at least 1 lower case character.")
continue
if not numbers.intersection(chars):
print("Your password must contain a number")
continue
npw = npwc
print("Your password has been changed")
break
This can be made more compact but yeah..
while True:
npw = input("Please enter new password.")
npwc = input ("Please confirm new password")
if npwc == npw:
if any(x.isupper() for x in npwc):
if any(x.islower() for x in npwc):
if len(npwc) >= 8:
if any (x.isdigit() for x in npwc):
npw=npwc
print("Your password has been changed")
#break # you probably want to exit the loop at this point
else:
print("Your password must contain a number")
else:
print("Your password must contain at least 8 characters.")
else:
print("Your password must contain at least 1 upper case character.")
else:
print("Your password must contain at least 1 lower case character.")
else:
print("Passwords don't match")
This looks like a job for regular expressions. Solution below:
import re
def password_validator(password):
if len(password) < 8:
return False, "Your password must contain at least 8 characters"
if not re.match('.*[0-9]', password):
return False, "Your password must contain a number"
if not re.match('.*[A-Z]', password):
return False, "Your password must contain at least 1 upper case character."
if not re.match('.*[a-z]', password):
return False, "Your password must contain at least 1 lower case character."
return True, "Your password has been changed"
while True:
npw = input("Please enter new password.")
npwc = input("Please confirm new password")
if npw != npwc:
print("Passwords don't match")
continue
is_valid, message = password_validator(npw)
print(message)
if is_valid:
break
You could also validate the whole thing in one go as:
pattern = """
(?=.*[a-z]) # use positive lookahead to see if at least one lower case letter exists
(?=.*[A-Z]) # use positive lookahead to see if at least one upper case letter exists
(?=.*\d) # use positive lookahead to see if at least one digit exists
[A-Za-z0-9##$%^&+=]{8,} # match any character in [] at least 8 times
"""
pwd_validator = re.compile(pattern, re.VERBOSE)
if pwd_validator.match(password):
# legit password
else:
# no match ask again
Hope this helps. The re.VERBOSE just makes this regular expression self-documenting so a lot easier to understand in future.