Using a regex in Python, how can I verify that a user's password is:
At least 8 characters
Must be restricted to, though does not specifically require any of:
uppercase letters: A-Z
lowercase letters: a-z
numbers: 0-9
any of the special characters: ##$%^&+=
Note, all the letter/number/special chars are optional. I only want to verify that the password is at least 8 chars in length and is restricted to a letter/number/special char. It's up to the user to pick a stronger / weaker password if they so choose.
So far what I have is:
import re
pattern = "^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$"
password = raw_input("Enter string to test: ")
result = re.findall(pattern, password)
if (result):
print "Valid password"
else:
print "Password not valid"
import re
password = raw_input("Enter string to test: ")
if re.fullmatch(r'[A-Za-z0-9##$%^&+=]{8,}', password):
# match
else:
# no match
The {8,} means "at least 8". The .fullmatch function requires the entire string to match the entire regex, not just a portion.
I agree with Hammish. Do not use a regex for this. Use discrete functions for each and every test and then call them in sequence. Next year when you want to require at least 2 Upper and 2 Lower case letters in the password you will not be happy with trying to modify that regex.
Another reason for this is to allow user configuration. Suppose you sell you program to someone who wants 12 character passwords. It's easier to modify a single function to handle system parameters than it is to modify a regex.
// pseudo-code
Bool PwdCheckLength(String pwd)
{
Int minLen = getSystemParameter("MinPwdLen");
return pwd.len() < minlen;
}
Well, here is my non-regex solution (still needs some work):
#TODO: the initialization below is incomplete
hardCodedSetOfAllowedCharacters = set(c for c in '0123456789a...zA...Z~!##$%^&*()_+')
def getPassword():
password = raw_input("Enter string to test: ").strip()
if (len(password) < 8):
raise AppropriateError("password is too short")
if any(passChar not in hardCodedSetOfAllowedCharacters for passChar in password):
raise AppropriateError("password contains illegal characters")
return password
import re
password=raw_input("Please give me a password: ")
if len(re.findall("[A-Za-z0-9##$%^&+=]",password))==len(password):
print("Great password")
else:
print("Incorrect password")
If you want to run it in python 3.0 and above change raw_input with input.
import re
password = input("Enter Password")
True if (re.fullmatch(r'^[A-Za-z0-9##$%^&+=]{8,}$', password)) else False
if however you wanted to make the second bits required, you could do the following:-
True if (re.fullmatch(r'^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.[##$%^&+=])[A-Za-z0-9##$%^&+=]{8,}$', password)) else False
Note: [0-9] in python is a subset of \d so you might want to stick to [0-9] read the following post https://stackoverflow.com/a/6479605/4170558
If you wan the program to continuously run until a correct password is inputted do the following.
import re
while True:
print('Input a strong password.')
password = input()
if re.match(r'[A-Za-z0-9##$%^&+=]{8,}', password):
print('Very nice password. Much secure')
break
else:
print('Not a valid password')
This regex validate if the password:
uppercase letters: A-Z
-lowercase letters: a-z
numbers: 0-9
any of the
special characters: !#£$%^&*()_+={}?:~[]]+
re.compile(r'^.*(?=.{8,10})(?=.*[a-zA-Z])(?=.*?[A-Z])(?=.*\d)[a-zA-Z0-9!#£$%^&*()_+={}?:~\[\]]+$')
But what if the user enters another special characters out of your list? Should you include all existing special characters? Another solution may be search what we expect to be in the password separately:
numbers: 0-9
lowercase letters: a-z
uppercase letters: A-Z
any special characters
No white space
p = password
def is_valid(p):
if (len(p) >= 8 and
re.search(r'\d+', p) and
re.search(r'[a-z]+', p) and
re.search(r'[A-Z]+', p) and
re.search(r'\W+', p) and not
re.search(r'\s+', p)):
return True
else:
return False```
Related
I am a high school programmer currently writing code in Python to strengthen my programming skills and am creating a basic signup page. I want my code to alert the user if their input for a username or password is invalid, but all of the answers I have seen so far are not very helpful. I have found "^[a-zA-Z0-9]*$" to be the most useful so far for detecting special characters such as asterisks and periods, but it seems to only work when a user uses all of the characters above instead of just the ones within the range of characters that satisfy the requirement. I will show my code below:
while not chosen_user:
chosen_user = input("""Enter the username that you would like. Please keep it between 6 and 15
characters. Do not use special characters such as '&', '#', or '!' in your username. Underscores are allowed.\n>""")
if (len(chosen_user) >= 6 or len(chosen_user) <= 15) and "^[a-zA-Z0-9_]*$" in chosen_user:
chosen_user = True
usernames_passwords[chosen_user] = ''
else:
print('Username does not meet the requirements. Please try again.')
chosen_user = False
while not chosen_pass:
chosen_pass = input("""Enter a password that contains no special characters. Password must be at
least 6 characters.\n>""")
if len(chosen_pass) >= 6 and "^[a-zA-Z0-9]*$" in chosen_pass:
chosen_pass = True
usernames_passwords[chosen_user] = chosen_pass
else:
print('Password is invalid. Please try again.')
chosen_pass = False
I cannot figure out how to get a password approved while only using some of the characters, and I have been struggling for a while. Any help would be nice.
**Also, keep in mind that I am in high school and would prefer to keep this code as simple as possible. Imports are okay, but I would like to understand how and when to use these things for future use. Thanks!!
Try this:
import re #--> import regular expressions module
while not chosen_user:
chosen_user = input("""Enter the username that you would like. Please keep it between 6 and 15
characters. Do not use special characters such as '&', '#', or '!' in your username. Underscores are allowed.\n>""")
if (len(chosen_user) >= 6 and len(chosen_user) <= 15) and re.search(r"^[A-Za-z0-9_]+$", chosen_user):
chosen_user = True
usernames_passwords[chosen_user] = ''
else:
print('Username does not meet the requirements. Please try again.')
chosen_user = False
while not chosen_pass:
chosen_pass = input("""Enter a password that contains no special characters. Password must be at
least 6 characters.\n>""")
if len(chosen_pass) >= 6 and re.search(r"^[A-Za-z0-9_]+$", chosen_pass):
chosen_pass = True
usernames_passwords[chosen_user] = chosen_pass
else:
print('Password is invalid. Please try again.')
chosen_pass = False
You can simplify your looping logic and also your string checking by using regular expressions:
import re
chosen_user = input("""Enter the ... allowed.\n>""")
while not re.match(r"^\w{6,15}$", chosen_user, flags=re.ASCII):
chosen_user = input('Username does not meet the requirements. Please try again.')
chosen_pass = input("""Enter a password ... least 6 characters.\n>""")
while not re.match(r"^[a-zA_Z]{6,}$", chosen_pass):
chosen_pass = input('Password is invalid. Please try again.')
You will find in the re docs:
"^"
(Caret.) Matches the start of the string, and in MULTILINE mode also matches immediately after each newline.
"$"
Matches the end of the string [...].
"\w"
Matches Unicode word characters; this includes most characters that can be part of a word in any language, as well as numbers and the underscore. If the ASCII flag is used, only [a-zA-Z0-9_] is matched.
"{m,n}"
Causes the resulting RE to match from m to n repetitions of the preceding RE, attempting to match as many repetitions as possible. For example, a{3,5} will match from 3 to 5 'a' characters. Omitting m specifies a lower bound of zero, and omitting n specifies an infinite upper bound.
while not chosen_user:
chosen_user = input("""Enter the username that you would like. Please keep it between 6 and 15
characters. Do not use special characters such as '&', '#', or '!' in your username. Underscores are allowed.\n>""")
if (len(chosen_user) >= 6 or len(chosen_user) <= 15) and "^[a-zA-Z0-9_]*$" in chosen_user:
chosen_user = True
usernames_passwords[chosen_user] = ''
else:
print('Username does not meet the requirements. Please try again.')
chosen_user = False
while not chosen_pass:
pas = input("""Enter a password that contains no special characters. Password must be at
least 6 characters.\n>""")
schar="#_!#$%^&*()<>?/\|}{~:]"
if len(pas)>=6:
for i in pas:
if i in schar:
choosen_pass=True
break
usernames_passwords[chosen_user] = chosen_pass
else:
print('Password is invalid. Please try again.')
chosen_pass = False
password = input(str("Please enter a password with a capital letter and a number: "))
for char in password:
if password.islower() and "1234567890" not in password:
print("Your password will need to have at least one number and at least one capitalized letter")
password = input("Please enter another password: ")
**The error phrase will print if a password is entered without a number or capital, but if a capital is used in the input the error string doesn't run even though the input is still missing a number. Same for if the input has a number but not a capital letter. I want both a capital letter and a number to be required for the input as you can probably tell. Thanks.
edit:
I don't want to know how to make a password requirement program. I specifically want to know why the "and not" is not working.**
I just happened to write this yesterday.
Season to taste :-)
import re
import getpass
while True:
pwd = getpass.getpass('please enter a password: ')
if len(pwd) >= 8 and re.search('[0-9]', pwd) and re.search('[A-Z]', pwd):
if pwd != getpass.getpass('please reenter password: '):
print('passwords do not match')
else:
break
else:
print('passwords must contain 8 characters and at least one uppercase letter and one digit')
print('approved pwd:', pwd)
I specifically want to know why the "and not" is not working.
"1234567890" not in password
is negation of "1234567890" in password which for password being str is checking if "1234567890" is substring of password.
Consider that:
print("123" in "123123123") # True
print("123" in "1") # False
print("123" in "321") # False
To check if any character from one str is present in second str you might check if intersection is not empty - just turn second str into set, get interesection with first, and use bool function on result, thus getting True if at least one of characters of first str is present in second and False otherwise:
x = "1234567890"
y = "sometextandnumber0"
print(bool(set(y).intersection(x))) # True
While preparing for my AS-Level Computer Science exam I came across a question in the pre-release material:
Prompt the user to input a User ID and check if the format of the ID corresponds with pre-defined formatting rules and output accordingly.
The Format (In order):
One upper case letter
Two Lower case letters
Three numeric characters (digits)
Example: "Abc123"
I came up with a solution using my language of choice(Python), however, I was wondering if there is a more elegant or better way to solve this. Especially the third check.
Here is my code:
#Task 2.2
u_id = input("Input User ID: ") #DECLARE u_id : string
numbers = [str(num) for num in range(10)]
#Checking if final 3 characters of User ID (u_id) are digits
for i in list(u_id[3::]):
if i not in numbers:
digit_check = False #DECLARE digit_check : bool
break
else:
digit_check = True
#User ID format check
if (u_id[0:1].isupper() == True) and (u_id[1:3] == u_id[1:3].lower()) and (digit_check == True):
print ("Correct Format")
else:
print ("Wrong Format")
Ignore the DECLARATION comments. They are an exam requirement.
Thanks
If you are allowed to import re:
import re
u_id = input("Input User ID: ") #DECLARE u_id : string
rex = re.compile("^[A-Z][a-z]{2}[0-9]{3}$")
if rex.match(u_id):
print("Correct format")
else:
print("Incorrect")
Explanation of expression:
^ represents the beginning of a string.
[A-Z] is a range, containing all uppercase letters (in the English alphabet).
[a-z] is a range, containing all lowercase letters.
[0-9] is a range, containing all numbers.
{n} specifies that n items (items are whatever is before the curly brackets) will be matched.
$ represents the end of the string.
Also, you can see more detailed explanations and test arbitrary strings against this regular expression here.
If you want to solve it without regular expressions (mind you, in this case they are the right tool!), you could do something like this:
id_format = [
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", # or string.ascii_uppercase etc.
"abcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyz",
"0123456789",
"0123456789",
"0123456789",
]
def check(input):
# check for same length
if len(input) != len(id_format):
return False
for test, valid in zip(input, id_format): # itertools.zip_longest can make
if test not in valid: # the length check unnecessary
return False
return True
check("Abc123") # True
check("abc123") # False
I want this function to work in my is_password_good function.
def is_ascii(some_string) :
for each_letter in some_string:
if ord(each_letter) < 128:
return False
return True
The is_good_password function makes certain the user's password is at least 10 characters long and that at least one uppercase and lowercase exists.
How can I pass my ASCII function to check if the user creates a passwords using at least one symbol by ASCII standards?
def is_good_password(password):
count_upper, count_lower = 0, 0
for characters in password:
if characters.isupper():
count_upper += 1
if characters.islower():
count_lower += 1
is_password_good = True
if len(password) <= 10:
print "Password is too weak, must be more than 10 characters long!"
is_password_good = False
if count_upper < 1 or count_lower < 1:
print "Password must contain at least one uppercase and one lowercase character!"
is_password_good = False
create_user(database)
print "Welcome! Username & Password successfully created!"
return is_password_good
You can check string.punctuation exist in string or not.
>>>string.punctuation
'!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~'
import re
def getmix(password):
Upper=len(set(re.findall(r'[A-Z]',password)))
Lower=len(set(re.findall(r'[a-z]',password)))
Nums=len(set(re.findall(r'[0-9]',password)))
Symb=len(set(re.findall(r'[~!##$%^&\*()_+=-`]')))
return (Upper, Lower, Nums, Symb)
Should give you a good starting point.
The function somestring.isalnum() will return False if not all characters in the string are alphabetics or numbers.
The precise definition of these categories are locale-dependent; make sure you know which locale you are using.
By the by, ASCII is only defined up to character code 127. If you go above 127, you need to know which character set and encoding you are dealing with. However, characters like # and ! are indeed defined in ASCII, and have character codes in the 30-something range. You are better off using library functions which abstract away the precise character codes, anyway.
has_symbol = False
for c in '~!##$%^&*()_+=-`':
if c in password:
has_symbol = True
break
if not has_symbol:
print "Password must contain at least one uppercase and one lowercase character!"
is_password_good = False
Always use the builtins, don't roll your own, so in that spirit, use the string module for a canonical list of symbols:
import string
symbols = string.punctuation
and printing symbols shows us these characters:
!"#$%&'()*+,-./:;<=>?#[\]^_`{|}~
You can pass to any the "one iterable in another" construction:
if any(char in symbols for char in some_string):
print 'password good'
However, I actually prefer the set methods instead of the above construction:
if set(symbols).intersection(some_string):
print 'password good'
but Triplee's advice on isalnum is just as potent, doesn't require importing the string module, and quite shorter.
if not some_string.isalnum():
print 'password good'
I have this code in python.
Actually i wanted to validate the password field at server side using python. i want password to be alphanumeric in nature and thats what i have done so far
def valid():
num = "[a-zA-Z0-9]"
pwd = "asdf67AA"
match = re.match(pwd, num)
if match:
return True
else:
return False
its always returning false . It does not hit the IF condition. whats that i am missing
You reversed the arguments of match
re.match(pattern, string, flags=0)
It should be
match = re.match(num, pwd)
You can do this to find out if the string is alphanumeric
pwd = "asdf67AA"
if pwd.isalnum():
# password is alpha numeric
else:
# password is not alpha numeric
You have miss placed the argument in method reverse it .
it will work.
But this also matched if you set symbol in your string.
so, i suggest you apply this things :
pwd ="test5456"
pwd.isalnum():
This method will only work for if your string contain string or digit.
if you want strongly want your password contain both numeric and string than this code will help you.
test = "anil13##"
new = tuple(test)
data = list(new)
is_symb =False
is_digit = False
is_alpha = False
for d in data :
if d.isdigit() :
is_digit = True
if d.isalpha():
is_alpha = True
if not d.isdigit() and not d.isalpha():
is_symb =True
break
if is_symb == False and is_digit == True and is_alpha == True:
print "pwd matchd::::"
else :
print "pwd dosen't match..."
Note :This code strongly work for numeric & symbol
Regards,
Anil
This is very simple answer and it is better to use regex for validation instead of wired if else condition.
import re
password = raw_input("Enter Your password: ")
if re.match(r'[A-Za-z0-9##$%^&+=]{6,}', password):
print "Password is match...."
else:
print "Password is not match...."
#6 means length of password must be atleast 6
you can do it by using isalnum() method of python
just by doing
pwd.isalnum()
it will tell wthether a number is alphanumeric or not and then will hit the if condiion