0

I'm having trouble getting the program to check all the factors for having a "strong password" without having to make a billion if statements.

I'm trying to make a password strength program where to password must have:

  1. at least 10 characters
  2. is mixed case
  3. at least one number
  4. a valid special character from "!@#$%^&*"

Code:

import re


def passwordChecker(password):
    tooShort = "Your password is too short, it must be at least 10 characters"
    noNum = "Your password does not have a number. Please add at least one number."
    notMixed = "Your password is not mixed case. Please choose a password with mixed case."
    noSpec = "Your password does not have a valid special character. Please add at least one valid special character."
    if len(password) >= 10 and re.search(r'[0-9]', password) and re.search(r'[A-Z]', password) \
            and re.search(r'[a-z]', password) and re.search(r'[$!@%^&*#]', password):
        print("Your password is valid")
    elif len(password) < 10:
        print(tooShort, "\n" +str(noNum), "\n" + str(notMixed), "\n" + str(noSpec))
    elif len(password) >= 10 and re.search(r'[A-Z]', password) and re.search(r'[a-z]', password):
        print(noNum, "\n" + str(noSpec))
    elif len(password) >= 10 and re.search(r'[$!@%^&*#]', password):
        print(notMixed, "\n" + str(noNum))


password = str(input("Enter a password: "))
passwordChecker(password)

While it works, kind of, I need to figure out a better system that is more... robust, I guess? Using regex is not a must-have, it's just the way I wound up doing it.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Hubert H.
  • 11
  • 5

2 Answers2

0

(?=.{10,})(?=.*[A-Z].*)(?=.*[a-z].*)(?=.*\d.*)(?=.*[\!\@\#\$\%\^\&\*].*)(?=^[\!\@\#\$\%\^\&\*a-zA-Z0-9]+$)^.*$ should meet each one of your needs, and is fairly easy to modify, as well.

  • (?=.{10,}) Ensure at least 10 characters.
  • (?=.*[A-Z].*) Check for at least 1 uppercase letter.
  • (?=.*[a-z].*) Check for at least 1 lowercase letter.
  • (?=.*\d.*) Check for at least 1 digit.
  • (?=.*[\!\@\#\$\%\^\&\*].*) Look for at least 1 symbol from your list.
  • (?=^[\!\@\#\$\%\^\&\*a-zA-Z0-9]+$) Ensure no symbols appear that AREN'T in your list.
  • ^.*$ The actual password to match.

If you don't want one or more of these rules, simply remove the positive lookahead that contains them.

Try it here!

Edit: here's a sample python program implementing the password checker.

import re

#loop forever
while(1==1):
  #get a password
  pword = input("password to test: ")

  #test it against the conditions
  if(re.match(
    "(?=.{10,})" + 
    "(?=.*[A-Z].*)" +
    "(?=.*[a-z].*)" +
    "(?=.*\d.*)" +
    "(?=.*[\!\@\#\$\%\^\&\*].*)(?=^[\!\@\#\$\%\^\&\*a-zA-Z0-9]+$)" +
    "^.*$", pword)
  ):
    #match: good password
    print("good")
  else:
    #failed one of the conditions: bad password
    print("bad")

Demo here!

Nick Reed
  • 4,989
  • 4
  • 17
  • 37
  • I'm sorry, but I don't understand that syntax. I don't quite know where to put that code in or how. I'm still a novice at this. – Hubert H. Oct 10 '19 at 15:55
  • @KevinJ. No worries! Have a look at the updated answer with some python sample code, as well as a demo to test it. – Nick Reed Oct 10 '19 at 16:01
  • Oh! That's a really nice way of doing it! I'm pretty sure I can find a way with my existing code to print statements based on what conditions they failed. Thanks, dude! – Hubert H. Oct 10 '19 at 16:17
  • @KevinJ. Glad to help! Please consider accepting the answer if it addresses your question, so future visitors know what worked. – Nick Reed Oct 10 '19 at 16:18
0

There are a few bugs in your code.

You can solve the problem by maybe defining five simple functions beside your own password_checker method. I did not fully check everything in the following code, you might want to check to see if there'd be still some bugs:

Test

import re


def password_checker(password):
    too_short = "Your password is too short, it must be at least 10 characters"
    no_num = "Your password does not have a number. Please add at least one number."
    not_mixed = "Your password is not mixed case. Please choose a password with mixed case."
    no_spec = "Your password does not have a valid special character. Please add at least one valid special character."
    unknown_problem = "Something is not right!"
    valid_pass = "Congrats! Your pass is valid!"

    if check_length(password) is True:
        print(too_short)

    if check_digit(password) is None:
        print(no_num)

    if check_lowercase(password) is None or check_uppercase(password) is None:
        print(not_mixed)

    if check_special_chars(password) is None:
        print(no_spec)

    if check_length(password) is False and check_special_chars(password) and check_digit(password) and check_lowercase(password) and check_uppercase(password):
        print(valid_pass)


def check_length(password):
    '''
    Returns True if length is smaller than 10
    '''
    return len(password) < 10


def check_digit(password):
    '''
    Returns an object if there is a digit
    '''
    return re.search(r'(?=.*[0-9])', password)


def check_lowercase(password):
    '''
    Returns an object if there is a lowercase letter
    '''
    return re.search(r'(?=.*[a-z])', password)


def check_uppercase(password):
    '''
    Returns an object if there is a uppercase letter
    '''
    return re.search(r'(?=.*[A-Z])', password)


def check_special_chars(password):
    '''
    Returns an object if there is a special char from this char class: [$!@%^&*#]
    '''
    return re.search(r'(?=.*[$!@%^&*#])', password)


password = str(input("Enter a password: "))
password_checker(password)
Community
  • 1
  • 1
Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    Thanks! While trying to get everything working on my own, I wound with an issue where even if the password was right, everything would print anyways. But this solves it for me! I can even put it into one function if I want to! – Hubert H. Oct 10 '19 at 16:02