Validation of a Password - Python
Asked Answered
G

15

8

So I have to create code that validate whether a password:

  • Is at least 8 characters long
  • Contains at least 1 number
  • Contains at least 1 capital letter

Here is the code:

def validate():
    while True:
        password = input("Enter a password: ")
        if len(password) < 8:
            print("Make sure your password is at lest 8 letters")
        elif not password.isdigit():
            print("Make sure your password has a number in it")
        elif not password.isupper(): 
            print("Make sure your password has a capital letter in it")
        else:
            print("Your password seems fine")
            break

validate()

I'm not sure what is wrong, but when I enter a password that has a number - it keeps telling me that I need a password with a number in it. Any solutions?

Ginetteginevra answered 13/12, 2016 at 9:38 Comment(2)
Possible duplicate of check if a string contains a numberPralltriller
Possible duplicate of Checking the strength of a password (how to check conditions)Woodie
P
16

You can use re module for regular expressions.

With it your code would look like this:

import re

def validate():
    while True:
        password = raw_input("Enter a password: ")
        if len(password) < 8:
            print("Make sure your password is at lest 8 letters")
        elif re.search('[0-9]',password) is None:
            print("Make sure your password has a number in it")
        elif re.search('[A-Z]',password) is None: 
            print("Make sure your password has a capital letter in it")
        else:
            print("Your password seems fine")
            break

validate()
Punner answered 13/12, 2016 at 9:54 Comment(1)
And for special characters, you can add ``` elif re.search('[^a-zA-Z0-9]',password) is None: print("Make sure your password has a special character in it") ```Acarid
G
7
r_p = re.compile('^(?=\S{6,20}$)(?=.*?\d)(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[^A-Za-z\s0-9])')

this code will validate your password with :

  1. min length is 6 and max length is 20
  2. at least include a digit number,
  3. at least a upcase and a lowcase letter
  4. at least a special characters
Geostatic answered 30/3, 2017 at 7:53 Comment(0)
S
5

password.isdigit() does not check if the password contains a digit, it checks all the characters according to:

str.isdigit(): Return true if all characters in the string are digits and there is at least one character, false otherwise.

password.isupper() does not check if the password has a capital in it, it checks all the characters according to:

str.isupper(): Return true if all cased characters in the string are uppercase and there is at least one cased character, false otherwise.

For a solution, please check the question and accepted answer at check if a string contains a number.

You can build your own hasNumbers()-function (Copied from linked question):

def hasNumbers(inputString):
    return any(char.isdigit() for char in inputString)

and a hasUpper()-function:

def hasUpper(inputString):
    return any(char.isupper() for char in inputString)
Salinasalinas answered 13/12, 2016 at 9:41 Comment(1)
"isupper checks if all the characters in the password is upper". No: ``"HELLO WORLD !!".isupper()` yields True. It checks that there's at least an uppercased letter and that no letter is lowercased.Gonta
C
2

Example:

class Password:
    def __init__(self, password):
        self.password = password

    def validate(self):        
        vals = {
        'Password must contain an uppercase letter.': lambda s: any(x.isupper() for x in s),
        'Password must contain a lowercase letter.': lambda s: any(x.islower() for x in s),
        'Password must contain a digit.': lambda s: any(x.isdigit() for x in s),
        'Password must be at least 8 characters.': lambda s: len(s) >= 8,
        'Password cannot contain white spaces.': lambda s: not any(x.isspace() for x in s)            
        } 
        valid = True  
        for n, val in vals.items():                         
           if not val(self.password):                   
               valid = False
               return n
        return valid                

    def compare(self, password2):
        if self.password == password2:
            return True


if __name__ == '__main__':
    input_password = input('Insert Password: ')
    input_password2 = input('Repeat Password: ')
    p = Password(input_password)
    if p.validate() is True:
        if p.compare(input_password2) is True:
            print('OK')
    else:
       print(p.validate())
Charbonneau answered 27/12, 2019 at 13:46 Comment(0)
W
1

You are checking isdigit and isupper methods on the entire password string object not on each character of the string. The following is a function which checks if the password meets your specific requirements. It does not use any regex stuff. It also prints all the defects of the entered password.

#!/usr/bin/python3
def passwd_check(passwd):
    """Check if the password is valid.

    This function checks the following conditions
    if its length is greater than 6 and less than 8
    if it has at least one uppercase letter
    if it has at least one lowercase letter
    if it has at least one numeral
    if it has any of the required special symbols
    """
    SpecialSym=['$','@','#']
    return_val=True
    if len(passwd) < 6:
        print('the length of password should be at least 6 char long')
        return_val=False
    if len(passwd) > 8:
        print('the length of password should be not be greater than 8')
        return_val=False
    if not any(char.isdigit() for char in passwd):
        print('the password should have at least one numeral')
        return_val=False
    if not any(char.isupper() for char in passwd):
        print('the password should have at least one uppercase letter')
        return_val=False
    if not any(char.islower() for char in passwd):
        print('the password should have at least one lowercase letter')
        return_val=False
    if not any(char in SpecialSym for char in passwd):
        print('the password should have at least one of the symbols $@#')
        return_val=False
    if return_val:
        print('Ok')
    return return_val

print(passwd_check.__doc__)
passwd = input('enter the password : ')
print(passwd_check(passwd))
Warfare answered 7/11, 2017 at 6:57 Comment(1)
Using return_val is non-pythonic. Just return False if it is not valid and True if it is.Cabral
B
1
''' Minimum length is 5;
 - Maximum length is 10;
 - Should contain at least one number;
 - Should contain at least one special character (such as &, +, @, $, #, %, etc.);
 - Should not contain spaces.
'''

import string

def checkPassword(inputStr):
    if not len(inputStr):
        print("Empty string was entered!")
        exit(0)

    else:
        print("Input:","\"",inputStr,"\"")

    if len(inputStr) < 5 or len(inputStr) > 10:
        return False

    countLetters = 0
    countDigits = 0
    countSpec = 0
    countWS = 0

    for i in inputStr:
        if i in string.ascii_uppercase or i in string.ascii_lowercase:
             countLetters += 1
        if i in string.digits:
            countDigits += 1
        if i in string.punctuation:
            countSpec += 1
        if i in string.whitespace:
            countWS += 1

    if not countLetters:
        return False
    elif not countDigits:
        return False
    elif not countSpec:
        return False
    elif countWS:
        return False
    else:
        return True


print("Output: ",checkPassword(input()))

With Regex

s = input("INPUT: ")
print("{}\n{}".format(s, 5 <= len(s) <= 10 and any(l in "0123456789" for l in s) and any(l in "!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~" for l in s) and not " " in s))

Module import

from string import digits, punctuation

def validate_password(p):
    if not 5 <= len(p) <= 10:
        return False

    if not any(c in digits for c in p):
        return False

    if not any(c in punctuation for c in p):
        return False

    if ' ' in p:
        return False

    return True

for p in ('DJjkdklkl', 'John Doe'
, '$kldfjfd9'):
    print(p, ': ', ('invalid', 'valid')[validate_password(p)], sep='')
Biogenesis answered 22/9, 2019 at 10:8 Comment(0)
M
1

Sure with regex there are easier answers, but this one of the simplest ways

from string import punctuation as p
s = 'Vishwasrocks@23' #or user input is welcome
lis = [0, 0, 0, 0]
for i in s:
    if i.isupper():
        lis[0] = 1
    elif i.islower():
        lis[1] = 1
    elif i in p:
        lis[2] = 1
    elif i.isdigit():
        lis[3] = 1
print('Valid') if 0 not in lis and len(s) > 8 else print('Invalid')
Manipur answered 14/12, 2020 at 18:9 Comment(0)
W
1

The simplest python validation using normal methods

password = '-'

while True:
    password = input(' enter the passwword : ')
    lenght = len(password)

    while lenght < 6:
        password = input('invalid , so type again : ')

        if len(password)>6:
            break

    while not any(ele.isnumeric() for ele in password):
        password = input('invalid , so type again : ')
    while not any(ele.isupper() for ele in password):
        password = input('invalid , so type again : ')
    while not any(ele not in "[@_!#$%^&*()<>?/|}{~:]" for ele in password):
        password = input('invalid , so type again : ')
    break
Winery answered 1/7, 2021 at 10:3 Comment(0)
D
0

What you need is using the any built-in function:

  • any([x.isdigit() for x in password]) will return True if at least one digit is present in password
  • any([x.isupper() for x in password]) will return True if at least one character is considered as uppercase.
Distil answered 13/12, 2016 at 9:43 Comment(0)
H
0

Maybe you can use regex expression:

re.search(r"[A-Z]", password)

Check uppercase letters.

re.search(r"[0-9]", password)

Check digits in password.

Hime answered 13/12, 2016 at 9:51 Comment(0)
I
0

Python 2.7 The for loop will assign a condition number for each character. i.e. Pa$$w0rd in a list would = 1,2,4,4,2,3,2,2,5. Since sets only contains unique values, the set would = 1,2,3,4,5; therefore since all conditions are met the len of the set would = 5. if it was pa$$w the set would = 2,4 and len would = 2 therefore invalid

name = raw_input("Enter a Password: ")
list_pass=set()
special_char=['#','$','@']
for i in name:
    if(i.isupper()):
      list_pass.add('1')
  elif (i.islower()):
      list_pass.add('2')
  elif(i.isdigit()) :
      list_pass.add('3')
  elif(i in special_char):
      list_pass.add('4')
if len(name) >=6 and len(name) <=12:
    list_pass.add('5')
if len(list_pass) is 5:
    print ("Password valid")
else: print("Password invalid")
Ioneionesco answered 7/11, 2018 at 5:41 Comment(1)
Code only answers are really discouraged. To help future readers, please explain what you are doing too!Lyssa
A
0
uppercase_letter = ['A', 'B','C', 'D','E','F','G','H','I','J','K','L','M','N','O',
            'P','Q','R','S','T','U','V','W','X','Y','Z']

number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

import re

info ={}

while True:

    user_name = input('write your username: ')

    if len(user_name) > 15:
        print('username is too long(must be less than 16 character)')
    elif len(user_name) < 3 :
        print('username is short(must be more than 2 character)')
    else:
        print('your username is', user_name)
        break


while True:   

    password= input('write your password: ')

    if len(password) < 8 :
        print('password is short(must be more than 7 character)')

    elif len(password) > 20:
        print('password is too long(must be less than 21 character)') 

    elif re.search(str(uppercase_letter), password ) is None :
        print('Make sure your password has at least one uppercase letter in it')

    elif re.search(str(number), password) is None :
        print('Make sure your password has at least number in it')

    else:
        print('your password is', password)
        break

info['user name'] = user_name

info['password'] = password

print(info)
Azotize answered 7/4, 2020 at 16:1 Comment(2)
Can you explain how and why your code answers the questions?Talion
@mike first of all , if you think my code is useful , pleas click on upwards arrow :) , and also my cose is readable , if you have problem with it , plz tell me :)Azotize
D
0

Password Complexity conditions:

  1. Must include at least one uppercase character

  2. Must include at least one lowercase character

  3. Must include at least one number

  4. Must include at least one special character

  5. Must have a length of at least 8 and a max of 20

     import re
     def validate():
         while True:
         password = raw_input("Enter a password: ")
         re_exp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,20}$"
         if re.search(re.compile(regex_exp),password):
             print("Your password seems fine")
         else:
             print("Password doees not matches with password complexity conditions")
             break
    
Doreathadoreen answered 12/7, 2022 at 10:24 Comment(0)
J
-1

Or you can use this to check if it got at least one digit:

min(passwd).isdigit()
Jacinto answered 24/2, 2018 at 14:43 Comment(1)
max(passwd).isupper() doesn't work at all, only in special casesMydriasis
C
-1

Most of the answers here have two problems:

  • They suggest bad rules for password validation which you should not follow
  • They talk only about validating for the existance of some types of characters and not about validating for the existance of only sensible characters (the inverse operation)

Rules you should not follow

  • You should not enforce that a password has an uppercase character, a lowercase character and a special character
  • The reason for this is that it prevents a common schema of strong passwords from being used
  • For example: A sequence of 4 or more randomly selected words, where the words are not "frequently used words" is considered to be a very strong password
  • This is because even if each word is only 5 characters long, the total password length will be 20 characters, this makes it resistant to brute force attack
  • The use of 4 words which are not commonly used also makes the password resistant to dictionary attacks
  • A sensible dictionary attack algorithm might use the top 10,000 most frequently used words. A password which uses 4 words out of a set of 10,000 is like a 4 letter password where there are 10,000 characters in the alphabet (almost - see below)
  • This is not strictly speaking exactly true, because the frequency of word use is not uniformly distributed (but neither is character usage) therefore a password cracking algorithm which uses a probabilistic dictionary attack might be more effective
  • This is why I say "words which are not commonly used". Including the word "the" in a random 4 word password is likely to result in a much less secure password for example. It might be not much more strong than a 4 word password, because one of the words has such a high frequency of appearance in the English language
  • To give an indication of the strength of this:
  • 10000^4 = 1x10^16
  • log72(10^16) = log10(10^16) / log10(72) ~= 8.61
  • Why 72? There are 26 characters in the English alphabet, plus 10 numbers, plus (approx) 10 symbols
  • 4 randomly chosen words chosen from the top 10,000 most frequently used words is equivalent to a random password of length 8.6 characters where the alphabet used for the choice of possible characters includes 72 symbols, under the assumption that words are chosen with uniform frequency as part of a dictionary attack (unlikely to be true in reality)

Regional considerations and sensible permissible character sets

Which characters you consider to be sensible permissable choices for a password input might vary depending on your region (or the anticpated region of your users) your language (the language of your system/website/users) and whether or not you expect your system and users to span multiple regions or be multi-lingual.

For example, a sensible password validation logic for English speaking users for a system expected to be used in regions where English is widely used might be:

regex_pattern = re.compile(r'^[a-zA-Z0-9_\.\+\*\?\^\$\(\)\[\]\{\}\|\\/=!@#%&-~;:$')

input_example = 'examplepasswordyoucantguessme'
regex_pattern.match(input_example)

This permits use of the regular alpha numeric characters, plus some special characters which are to be found on most keyboards internationally.

  • _, ., +, *, ?, ^, $, (, ), [, ], {, }, |, \, /, =, !, @, #, %, &, -, ~, ;, :

It does not include the characters BACK_QUOTE, ' or ".

Characters generated by common password generators, such as Google Chrome

  • I am currently doing some research on this
  • It would be frustrating for a user if a commonly used password generator generated passwords which were then not accepted by any validation logic you write
Cabezon answered 12/7, 2024 at 10:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.