Python password strength [duplicate] - python

This question already has answers here:
Checking the strength of a password (how to check conditions)
(6 answers)
Closed 9 years ago.
I am programming a password strength code on python and i'm trying to find out if my password (p) contains a number, I have found out how to see if it contains upper and lower case letter by p.isupper() or p.islower(). I have also put them two together. My friend has told me how to see if the password only contains number but I need your help now.
running=True
while running:
p=raw_input("What is your Password? ")
if len(p) <6:
print "Your Password is too short"
if len(p) >12:
print "Your Password is too long"
if len(p) == 6 or 7 or 8 or 9 or 10 or 11 or 12:
print "Password Length OK"
running=False
print "Loop Broken" #this will be deleted, only for my help now
if p.isupper():
print "Your Password is weak as it only contains capital letters"
if p.islower():
print "Your Password is weak as it only contains lower case letters"
if p.isupper and p.islower:
print "Your Password is of medium strength, try adding some numbers"
try:
int(p)
print "Your Password is weak as it only contains numbers"
except (ValueError, TypeError):
pass
All I need now is the code for, if the password contains lower or upper case letters and numbers.

To me, regex would definitely be the easiest way of going about this.
Given a sample password password, the way you would check it would be:
import re
# Check if contains at least one digit
if re.search(r'\d', password):
print "Has a digit"
# Check if contains at least one uppercase letter
if re.search(r'[A-Z]', password):
print "Has uppercase letter"
# Check if contains at least one lowercase letter
if re.search(r'[a-z]', password):
print "Has lowercase letter"
For your other pieces, you can continue to use .isupper() and .islower().
By the way, this portion of your code:
if p.isupper and p.islower:
print "Your Password is of medium strength, try adding some numbers"
Will not function how you want it to. First, you're not actually calling the methods, since you haven't put the parentheses--you need to write if p.isupper() and p.islower():. Second, this doesn't actually do what you want it to. You're trying to check that it contains both lowercase and uppercase numbers. Instead, you're checking both that it is completely uppercase and completely lowercase, and obviously it can't be both, so that if statement will always return False. Instead, you'll want to use something like:
if re.search(r'[a-z]', password) and re.search(r'[A-Z]', password):
Or, alternatively, without re:
import string
if any(letter in string.ascii_lowercase for letter in password) and \
any(letter in string.ascii_uppercase for letter in password):
Or:
if any(letter.islower() for letter in password) and \
any(letter.isupper() for letter in password):
I happen to prefer re because it's more concise.

I guess you want to check whether your password contains all of these : lowercase, uppercase and digits.
>>> from string import ascii_lowercase, ascii_uppercase, digits
>>> s_lc = set(ascii_lowercase)
>>> s_uc = set(ascii_uppercase)
>>> s_d = set(digits)
def func(strs):
s = set(strs)
return all(s & x for x in (s_lc,s_uc,s_d ))
...
>>> func('fooBar09')
True
>>> func('fooBar')
False
>>> func('900')
False
>>> func('900aB')
True
Secondly len (p) == 6 or 7 or 8 or 9 or 10 or 11 or 12 is going to be evaluated as:
(len(p) == 6) or 7 so if len(p) is 6 then it returns True else 7(which is a Truthy value as well)
it should be : if 6 <= len(p) <= 12
>>> 7 or 8 or 9 or 10 or 11 or 12
7
Use while True instead of using a flag variable, and you need if-elif-else conditions here not if-if:
while True:
p=raw_input("What is your Password? ")
le = len(p)
if le <6:
print "Your Password is too short"
elif le >12:
print "Your Password is too long"
elif 6 <= le <= 12:
print "Password Length OK"
break

Related

Python - Password Validation program

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)}")

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.

How to check if a string contains at least 2 digits and no spaces?

I have to build a program where you enter a password. The password must contain at least 8 characters, start with a letter, have both upper and lower case letters, have no spaces and at least 2 digits.
I have everything else down except for the last 2.
I tried using a for loop to see if there are spaces or digits, but it will only work if the whole password consists of spaces or digits. If there is a number or a space, if prints off the error message for as many characters there are in the password, not just for how many digits or spaces there are. I know this is happening because of the for loop, but I'm stuck on how to fix it.
Here is what I have so far:
again = 'y'
while again == 'y':
minimum_characters = 8
error = 0
print('Password must contain 8 characters, start with a letter,')
print(' have no blanks, at least one uppercase and lowercase letter,')
print(' and must contain at least 2 digits.')
password = input('Enter a password: ')
passlength = len(password)
#validity checks for errors
if passlength < minimum_characters:
error += 1
print (error, '- Not a valid password. Must contain AT LEAST 8 characters. PW entered has', passlength, '.')
if not password[0].isalpha():
error += 1
print(error, '- The password must begin with a letter.')
if password.isalpha():
error += 1
print(error, '- The password must contain at least 2 digits.')
if password.isupper():
error += 1
print(error, '- You need at least one lower case letter.')
if password.islower():
error += 1
print(error,'- You need at least one upper case letter.')
again = input('Test another password? (Y or N): ')
again = again.lower()
if " " in password:
error += 1
print(error, '- Not a valid password. It contains spaces.')
if len([x for x in pwd if x.isdigit()]) < 2:
error += 1
print(error, '- The password must contain at least 2 digits.')
User regular expression
import re
sequence = "1Sentence1e"
if re.match("(?:\d.*?){2,}", sequence):
print("Match!")
else:
print("Not match!")
Fiddle: http://tpcg.io/73SyIc
Regular expression match javascript syntax
"(...) have no spaces and at least 2 digits."
A few options that will work for counting the number of occurrences of any character/digit. Simply replace with what you need (digits and spaces in the examples):
if any([x for x in password if x == " "]):
# 1 or more spaces in password
if password.count(" ") > 0:
# 1 or more spaces in password
if len([x for x in password if x.isdigit()]) < 2:
# less than 2 digits
To report an error when the string contains less than 2 digits you can use:
if sum(map(str.isdigit, password)) < 2:
Also, your checks for uppercase and lowercase letters are incorrect:
if password.isupper():
checks if all characters are uppercase. To check if any character is uppercase you can use:
any(map(str.isupper, password))

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

Categories