Python - Password Validation program - python

I am trying to make a program that carries out password validation when a user is making an account for this first time and has to enter a new password.
The password has to be more than 8 letters, contain an upper case letter, a lower case letter and a number.
I've done the following code, and it doesn't work at the moment. I think it's because islower() only works if all characters in the string are lower, same with isupper but for uppercase letters. How can I solve this issue, to get a nice clean solution for the requirements? Thanks
while loop:
pass1 = input('type a password: ')
if len(pass1) > 8 and pass1.islower() and pass1.isupper() and pass1.isdigit():
print('password successful')
break
else:
print('Password not valid, please retry')

Create another if else statement where you check islower method return true or false or set it equal to another boolean value then use that value in the second(which is your main if statement) statement then run it.

The condition that you are looking for is as follows: the password must be alphanumeric, but it must not consist of all lower-case letters, it must not consist of all upper-case letters, it must not consist of all letters, and it must not consist of all digits:
pass1.isalnum() and not pass1.isupper()\
and not pass1.islower()\
and not pass1.isalpha()\
and not pass1.isdigit()

This should work.
def anyLower(s):
return s.upper() != s
def anyUpper(s):
return s.lower() != s
def anyDigit(s):
return any(char.isdigit() for char in s)
while True:
userInput = input("Type a password: ")
if len(userInput) > 8 and anyLower(userInput) and anyUpper(userInput) and anyDigit(userInput):
print("Password successful")
break
else:
print("Password not valid, please retry")
anyLower() function converts the string to uppercase and checks if it changes, if it has changed, then the string must contain at least one lowercase character. anyUpper() works in a similar way.
anyDigit() iterates through all of the characters in the string and returns true if any of the characters are digits using the any() function.

You can try utilizing the built-in any() method along with the built-in map() method to check if any of the characters in the string, mapped with your choice of str method, returns True:
conditions = str.islower, str.isupper, str.isdigit
while True:
pass1 = input('type a password: ')
if len(pass1) > 8 and all(any(map(c, pass1)) for c in conditions):
print('password successful')
break
else:
print('Password not valid, please retry')

The password has to be more than 8 letters, contain an upper case letter, a lower case letter and a number.
It's good programming practice to code to functional requirements so it would be useful to have a specific function such as is_password_valid().
And, since the intent is to check if all the conditions are met, you can exit early before needing to check all the characters (possibly many times) as some of the other answers here do. In other words, something like (with a test harness):
import sys
def is_password_valid(password):
if len(password) <= 8:
return False
has_upper, has_lower, has_digit = False, False, False
for character in password:
if character.islower(): has_lower = True
elif character.isupper(): has_upper = True
elif character.isdigit(): has_digit = True
if has_lower and has_upper and has_digit:
return True
return False
chs = ['1', 'a', 'B', '_']
for ch1 in chs:
for ch2 in chs:
for ch3 in chs:
for ch4 in chs:
str1 = ch1 + ch2 + ch3 + ch4 + "....."
print(f"{str1} : {is_password_valid(str1)}")

Related

How to write a python function to check if a user input for a password is not strong?

I need to write a code for an assignment that will take user input of a password (as a string) and lets the user know what elements of the input make the password weak.
The requirements are that the password needs to be at least 8 characters in length, include both upper and lower case letters, and include numbers. My code doesn't need to determine if the password is strong, just why it is weak if it is weak.
so far the code I have written is as follows:
size = len(password)
if size < 8:
print('not long enough')
if password.isalnum():
pass
else:
for x in password:
if x.isupper():
pass
else:
print('no upper case')
for y in password:
if y.islower():
pass
else:
print('no lower case')
return
I made some changes and used the .isalnum operator after my test run returned multiple lines of 'no upper case' and 'no lower case'.
I would greatly appreciate if anyone could nudge me in the right direction as this has confused me for a bit now
Without regex you can use any and str.isnumeric
if not any(map(str.isnumeric, password):
print('No numbers')
I would rather go with regex.
In [122]: def validate(password):
...: return True if re.match("(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}", password) else False
...:
In [123]: validate("helloas")
Out[123]: False
In [124]: validate("helH12asfgvGh")
Out[124]: True
(The other answers have already given you good answers, so this isn't an full answer, it's just an explanation of what is going wrong.) The area of your code that is causing the problem is
for x in password:
if x.isupper():
pass
else:
print('no upper case')
for y in password:
if y.islower():
pass
else:
print('no lower case')
You are looping over the entire password, checking if each character is uppercase, and then printing out "no upper case" if it isn't. The problem is that if a single character of the word isn't uppercase, "that_character_that_isn't_uppercase".isupper() will return false, and print the error statement. For example, the password PaSSWORD will return one "no upper case", since "a".isupper() is False. The password passworD will return 7 "no upper case"s, since the characters p,a,s,s,w,o,r are all lowercase. The same thing is happening with the x.islower() test, you are seeing if each individual character is lowercase. I would implement something like this:
#password.islower() will return true if all the entire string is lowercase(and thus not uppercase)
if password.islower():
print("No upper case")
elif password.isupper():
print("No lower case")
#Again, password.isupper() sees if all letters are uppercase(which means that there is no lowercase letters).
Hope this helped!
Lots of python password checkers online, for example: https://www.geeksforgeeks.org/password-validation-in-python/
Here's a quick console program you can call like:
$ python3 password_checker.py "Testf7788790##$"
Testing password: Testf7788790##$
Password is valid: True
$ python3 password_checker.py "insecurePassword"
Testing password: insecurePassword
Password should contain at least one number
Password is valid: False
Contents of password_checker.py:
#!/usr/bin/python
import sys
def password_check(passwd):
symbols = ['!', '#', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=']
isValid = False
if len(passwd) < 10:
print('Password should be at least 10 characters')
elif not any(char.isdigit() for char in passwd):
print('Password should contain at least one number')
elif not any(char.isupper() for char in passwd):
print('Password should contain at least one uppercase character')
elif not any(char.islower() for char in passwd):
print('Password should contain at least one lowercase character')
elif not any(char in symbols for char in passwd):
print('Password should contain at least one special character from list: ', symbols)
else:
isValid = True
return isValid
arguments = sys.argv
if len(arguments) < 2:
print('No password could be parsed by argv')
valid_password = False
else:
password = arguments[1]
print('Testing password: ', password)
valid_password = password_check(password)
print('Password is valid: ', valid_password)

Password can only contain number letters and underscores

The assignment is:
Write a Python program which prompts the user to create a user account and checks whether the provided user name and password are legal.
Note: A password should start with a letter and only consists of letters, numbers and the underscore symbol "_". The length should be between 8 to 16.
I'm having trouble with the "a password should start with a letter and only consists of letters, numbers and the underscore symbol "_". " part. (I know it's not the most elegant code)
username=input("Please enter a username:")
usepass=input("Please enter a password:")
#username
if len(username)<6 or len(username)>12:
print("Username is incorrect length. Your username must be between 6 and 12 characters.")
if username.isalnum() == False:
print("Username must only contain letters and numbers.")
username1=username[0]
if username1.isnumeric()== True :
print ("Your username must start with a letter")
#password
if len(usepass)<8 or len(usepass)>16:
print("Password is incorrect length. Your password must be between 8 and 16 characters.")
usepass1=usepass[0]
if usepass1.isalpha()==False:
print("Your password must start with a letter")
if usepass.isalnum()==False:
print("Your password must only contain numbers, letters and underscores.")
Rather than use the isalnum method, lets try to solve this on your own. The main thing you're lacking here is a loop. For example, if I want to test every letter, I can loop over the letters, and use the ord method to verify that every letter is in the right range.
You should structure your methods to test each of the unique conditions as stated in the question. If it passes all the conditions you can return true at the end.
def is_valid_user(username):
# a user name should start with a letter
is_first_lower = ord('a') <= ord(username[0]) <= ord('z')
is_first_upper = ord('A') <= ord(username[0]) <= ord('Z')
if not (is_first_lower or is_first_upper):
return False
# only consists of letters and numbers
for character in username:
is_lower = ord('a') <= ord(character) <= ord('z')
is_upper = ord('A') <= ord(character) <= ord('Z')
is_number = ord('0') <= ord(character) <= ord('9')
if not (is_lower or is_upper or is_number):
return False
# check the other cases like "The length should be between 6 and 12"
...
# All the tests passed so return true
return True
Now you can think about how you can make an is_valid_password method. This method should be similar, but have a few different conditions. Bonus: Think about how you can make other methods to share checks between the is_valid_user and is_valid_password methods.
i solved it by creating a new variable that removes an underscore and uses .isalnum to compare that variable
rmveudrsre = usepass.replace("_", "")
if rmveudrsre.isalnum()==False:
print("Your password must only contain numbers, letters and underscores.")

Making a valid password checker. Can not get my program to get through the if conditions to print a valid password

I have been assigned the following exercise as homework:
Some Web sites impose certain rules for passwords. Write a function that checks whether a string is a valid password. Suppose the password rules are as follows:
A password must have at least eight characters.
A password must consist of only letters and digits.
A password must contain at least two digits.
Write a program that prompts the user to enter a password and displays valid password if the rules are followed or invalid password otherwise.
I know there's a more efficient and proper way of doing this but i'm just starting out so I don't necessarily need to be those right now. Just want to finish this question.
The counter/ accumulator works and I don't get any errors but I can not fulfill the if condition correctly so that this program prints "valid password"
password = str(input("Enter in a password to be checked: "))
def valid_password_checker(password):
from string import ascii_lowercase as alphabet
digits = '0123456789' # creates a string of digits
digit = 0 # acc for digits
length = 0 # acc for length
for char in password: # calls on each character in string
if char in alphabet:
length += 1
if char in digits:
digit += 1
if digit >= 2:
flag = True
if length >= 8 and digit is True:
print("valid password")
else:
print("Password does not contain enough characters or digits.")
else:
print("Password does not contain enough digits.")
valid_password_checker(password)
The problem with your existing code is that the variable digit is a number, and therefore doing digit is True as you have done in your if statement, always return False. If you remove digit is True, then your existing solution will work. Take a look however at my version:
def valid(password):
digits = 0
characters = 0
for char in password:
if char.isalpha():
characters += 1
elif char.isdigit():
digits += 1
characters += 1
if characters >= 8:
if digits >= 2:
print("Password is valid")
else:
print("Password doesn't contain enough digits")
else:
print("Password doesn't contain enough characters")
I have made the following modifications from your original:
Used the built-in function str.isdigit() for checking if a character is a digit.
Used the built-in function str.isalpha() for checking if a character is a letter of the alphabet
Moved everything but the counting operations outside of the for loop, so that the function doesn't print multiple things
If you want, you can undo the first two changes, if you're worried about your teacher knowing you asked for help. However, I wouldn't turn in the solution that prints "Password doesn't contain enough digits" as many times as there are characters in the inputted password.
you can write something like this:
password = str(input("What is the password that you want to validate: "))
def get_digits(password):
return [i for i in password if i.isdigit()]
numbers = ''.join(get_digits(password))
if (len(password) < 8) or (len(numbers) < 2):
print(password, "is an invalid password")
else:
print(password, "is a valid password")
nice and simple.

Checking password input for integers, capitals and lowercase?

I am doing some work for my computing class at school and we need to ask for input of a password. The input needs to be between 6 and 12 characters, and contain uppercase, lowercase and numbers in it. I have this so far :
import sys
import os
def checkPass():
passLoop = True
while passLoop:
print("Welcome user!")
x = len(input("Please enter your password, between 6 and 12 characters. "))
if x < 6:
print("Your password is too short")
r = input("Please press any key to restart the program")
elif x > 12:
print("Your password is too long")
r = input("Please press any key to restart the program")
else:
print("Thank you for entering your password.")
print("Your password is strong. Thank you for entering!")
passLoop = False
checkPass()
I need your help checking for uppercase, lowercase and integers. I'm only young so please don't be too harsh!
^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?\d).{6,12}$
You can try this.This employs re.
You can use it like
import re
if re.match(r"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?\d).{6,12}$",pass,re.M):
print "valid"
else:
print "invalid"
See demo.
http://regex101.com/r/dZ1vT6/28
let's assume you have the password stored in a variable named passwd.
Then we can take your literal requirements and write checks for them:
The input needs to be between 6 and 12 characters,
if not 6 <= len(passwd) <= 12: ...
and contain uppercase,
if not any(c.isupper() for c in passwd): ...
lowercase
if not any(c.islower() for c in passwd): ...
and numbers in it.
if not any(c.isdigit() for c in passwd): ...
On a side note: you really should not limit the length of passwords.
the any function in combination with a map can be helpful. The map function iterates over all characters of the given string and test via the given lambda function if the character is an uppercase. The is consumed by the any function which returns true on the first true from the map function
>>> any(map(lambda a:a.isupper(),"aba"))
False
>>> any(map(lambda a:a.isupper(),"aBa"))
True
you can wrap that into a separate function like
>>> def test(passwd,func):
return any(map(func,passwd))
>>> test("aBa",str.isupper)
True
>>> test("ab0",str.isdigit)
True
>>> test("aBa",str.islower)
True

Having trouble learning how to look at individual characters in a string checking for case or digit

I am trying to write a simple password checker for homework assignment, looking for at least one capital, one lower case, one digit, and it needs to be 6 or more chars.
I have searched and searched on here and elsewhere, but either what I read doesn't match our instruction, or the replies are more advanced than myself. Any help I get will be cited as a comment in my assignment.
This is just the part of my code which checks for caps, it only looks at the whole string, not the individual characters and I can't seem to find the solution.
passwd = input('enter password: ') ## we are actually using (sys.agrv)
## but I am using this for testing
character = passwd[0:]
lcase_bad = False
for character in passwd:
if not character.islower() > 1:
lcase_bad = True
if lcase_bad:
print('Password must include lowercase letters ')
else:
print('password accepted')
for character in passwd:
Here you're iterating through each letter of the input.
When you do if not character.islower() > 1:, it will always be True. .islower() returns either True or False, depending on if the string is a capital letter or not. not False == 1, because boolean is a subclass of int. not True == 0. Both are not greater than one.
You can just do something like:
capital = False
lowercase = False
number = False
if len(passwd) < 6:
print 'That was not more than 6 characters'
else:
for character in passwd:
if character.islower():
lowercase = True
elif character.isupper():
capital = True
elif character.isdigit():
number = True
if capital and lowercase and number:
break
else:
print 'That did not have a capital letter, lowercase letter, and a digit'
Of course this is useful if you want to tell the person what the password didn't have. However, you can also just do one test instead.
Just check for all those conditions one after another:
mystring = input("enter password: ")
if any(c.isupper() for c in mystring) \ # There is an uppercase letter
and any(c.islower() for c in mystring) \ # There is a lowercase letter
and any(c.isdigit() for c in mystring) \ # There is a number
and len(mystring) > 5: # The length is 6 or greater
# string passed all tests
else:
# One or more tests failed--input is bad.
You've almost got it! If you remove the > 1 from your code (which won't really do anything useful), you get this:
lcase_bad = False
for character in passwd:
if not character.islower():
lcase_bad = True
It just happens that this will test to see if the entire string is made of lowercase letters. If it is, lcase_bad will remain False; otherwise, it will become True. It should not be an extreme leap of faith to see that if you flip the False and True around and call it lcase_good, you can see whether at least one character is lowercase.
As iCodez notes, you can also rewrite it using any with a generator comprehension. It reads fairly easily:
if any(character.islower() for character in passwd):
However, you probably haven't gotten to generator comprehensions, so it might be best to stay with a for loop for clarity's sake.

Categories