I wanted to learn some regex, but learning regex is super boring so I decided to write a password validator that will validate a password with regular expressions.
How it works:
- You enter a password that has no echo thanks to the getpasslibrary
- The password is run against five different validations such as, upper case, lower case, special character, and digits. These are done by using the re(regex) library.
- If the password does not pass one of the validations it will output a random password using the randomlibrary that will match the given guidelines.
What I would like to know is:
- Are there better ways to create a random string?
- Are there better regular expressions I could use to verify that password?
Source:
import getpass
import re
import random
def random_password(length=3):
    """ Create a a random password to display if the
       primary validation fails. """
    valid_upcase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    valid_lowcase = 'abcdefghijklmnopqrstuvwxyz'
    valid_specs = '!$@&'
    valid_digits = '1234567890'
    return ''.join((random.choice(valid_upcase) + random.choice(valid_lowcase) + random.choice(valid_specs) + random.choice(valid_digits) for i in xrange(length)))
def length_error(password):
    """ Validate that the password is over 8 characters
       and no more than 20 characters. """
    if 8 > len(password) :
        return False
    else:
        return True
def lower_error(password):
    """ Confirm that the password contains at least one
       lower case letter """
    if re.search(r"[a-z{1,9}]", password) is None:
        return False
    else:
        return True
def symbol_error(password):
    """ Make sure that the password contains at least one
       of the following special characters: ! @ $ & """
    if re.search(r"[!@$&{1,5}]", password) is None:
        return False
    else:
        return True
def upcase_error(password):
    """ Confirm that the password contains at least one
       upper case character. """
    if re.search(r"[A-Z{1,5}]", password) is None:
        return False
    else:
        return True
def digit_error(password):
    """ Confirm that the password contains at least one
       digit. """
    if re.search(r"\d{1,5}", password) is None:
        return False
    else:
        return True
def prompt(info):
    """ Get the password without echo. """
    return getpass.getpass(info) 
    #return raw_input(info)  # # Uncomment this for echo
def validate_password(password):
    """ Where the validation occurs, if the password does
       not pass one of the following tests, it will output
       a random string that does pass the test. """
    if lower_error(password) is False or upcase_error(password) is False:
        print "Password did not match the uppercase or lowercase requirements."
        print "Random password to use: {}".format(random_password())
    elif digit_error(password) is False or symbol_error(password) is False:
        print "Password did not match the integer and special character requirements."
        print "Random password to use: {}".format(random_password())
    elif length_error(password) is False:
        print "Password did not meet the length requirements."
        print "Password must be over 8 characters and no more then 20 characters"
        print "Random password to use: {}".format(random_password())
    else:
        print "Password validated successfully."
def obtain_password():
    """ Main method. """
    password_to_verify = prompt("Enter password: ")
    validate_password(password_to_verify)
if __name__ == '__main__':
    obtain_password()
