Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Simple Password Checker
#1
I've been trying to write a script that simply checks the strength of a password but the results aren't satisfactory. I know there are other ways to do it but I want to accomplish the task with the 'for' loop method:

import string

def checkPasswordStrength(password=' '):
    
    lowy = string.ascii_lowercase
    uppy = string.ascii_uppercase
    digity = string.digits
    puncy = string.punctuation
    try:    
        if len(password) <= 6:
            print("Password must be at least 7 characters")
    finally:
        for i in password:
            if i not in lowy:
                print("At least a lowercase must be included")
            elif i not in uppy:
                print("At least an uppercase letter must be included")
            elif i not in digity:
                print("At least a number must be included")
            elif i not in puncy:
                print("At least a special character must be included")
            else:
                print('Now That is a Strong Password!')


checkPasswordStrength('Billycash')
I get this response:
Output:
At least a lowercase must be included At least an uppercase letter must be included At least an uppercase letter must be included At least an uppercase letter must be included At least an uppercase letter must be included At least an uppercase letter must be included At least an uppercase letter must be included At least an uppercase letter must be included At least an uppercase letter must be included
Reply
#2
You are forcing each letter to be uppercase, lowercase, a number and a special character. That is rather stringent. Maybe you need to process every character and keep a tally of what requirements are met. After you process all the letters you can then decide if the password needs an upper case character to be valid.
bowlofred likes this post
Reply
#3
I would us a list to keep track of which elements have been included correctly. Here's an example:

def checkPasswordStrength (password=' ') :
	special_characters = '!@#$%^&*()'
	strength = [0, 0, 0, 0, 0]
	messages = ('At least one lowercase letter must be included.',
			'At least one upper case letter must be included.',
			'At least one number must be included.',
			'At least one special character must be included.',
			'Password must be at least 7 characters long.')
	for letter in password :
		if letter.islower () :
			strength [0] = 1
		elif letter.isupper () :
			strength [1] = 1
		elif letter.isdigit () :
			strength [2] = 1
		elif letter in special_characters :
			strength [3] = 1
	if len (password) > 6 : 
		strength [4] = 1
	print ()
	for count in range (len (strength)) :
		if strength [count] == 0 :
			print (messages [count])
	if 0 in strength :
		return False
	else :
		print ('Your password is strong.')
		return True 
herobpv and Dexty like this post
Reply
#4
What's the purpose of the try/finally? The only reason that should throw an exception is if password doesn't have a length. In that case, it's not a str, so you probably don't want to be trying to look at characters inside it in the finally block.
Reply
#5
The reason the error is flagging is because it isn't checking if the letters meet one requirement, it is checking if each letter meets all of them, so a lowercase I flags as not being uppercase, or a symbol, or a number.

Logically it would be better if you had one message eg "Your PW must include one uppercase and one lowercase...." and then have one if statement to check it.

for i in password:
    if i not in lowy and i not in uppy and len(i) < 7 and....:
        print("Your PW must include....")
    else:
        print("Much Strong, Many Wow.")
Dexty likes this post
while dad_has_cigs == True:
    happiness = True
    if dad_has_cigs == False:
    print("Dad come home!")
    happiness = not happiness
    break
Reply
#6
(Sep-21-2021, 09:35 PM)deanhystad Wrote: You are forcing each letter to be uppercase, lowercase, a number and a special character. That is rather stringent. Maybe you need to process every character and keep a tally of what requirements are met. After you process all the letters you can then decide if the password needs an upper case character to be valid.

(Sep-21-2021, 10:50 PM)BashBedlam Wrote: I would us a list to keep track of which elements have been included correctly. Here's an example:

def checkPasswordStrength (password=' ') :
	special_characters = '!@#$%^&*()'
	strength = [0, 0, 0, 0, 0]
	messages = ('At least one lowercase letter must be included.',
			'At least one upper case letter must be included.',
			'At least one number must be included.',
			'At least one special character must be included.',
			'Password must be at least 7 characters long.')
	for letter in password :
		if letter.islower () :
			strength [0] = 1
		elif letter.isupper () :
			strength [1] = 1
		elif letter.isdigit () :
			strength [2] = 1
		elif letter in special_characters :
			strength [3] = 1
	if len (password) > 6 : 
		strength [4] = 1
	print ()
	for count in range (len (strength)) :
		if strength [count] == 0 :
			print (messages [count])
	if 0 in strength :
		return False
	else :
		print ('Your password is strong.')
		return True 

This method worked. Thank you for the insight.
Reply
#7
Yesterday I posted an alternative but I do not see it now. It can be modified to produce the same output if desired.

#import sys
import string
  
def checkPasswordStrength(password):

    if len(password) <= 6:
        print("Password must be at least 7 characters")
        return
    teststring = "luds"
    testlist = list(teststring)
    special_characters = '!@#$%^&*()'
    for letter in password :
        if letter.islower() :
            testlist[0] = 'X'
        elif letter.isupper() :
            testlist[1] = 'X'
        elif letter.isdigit() :
            testlist[2] = 'X'
        elif letter in special_characters :
            testlist[3] = 'X'
    test = ''.join(testlist)
    if test == "XXXX":
        print("Password is valid")
        return
    message = "Password is not valid; missing:"
    if testlist[0] == 'l':
        message += " lowercase letter ";
    if testlist[1] == 'u':
        message += " upper case letter ";
    if testlist[2] == 'd':
        message += " digit ";
    if testlist[3] == 's':
        message += " special character ";
    print(message)
 
 
checkPasswordStrength('Billycash')
Dexty likes this post
Reply
#8
(Sep-21-2021, 09:35 PM)deanhystad Wrote: You are forcing each letter to be uppercase, lowercase, a number and a special character. That is rather stringent. Maybe you need to process every character and keep a tally of what requirements are met. After you process all the letters you can then decide if the password needs an upper case character to be valid.

(Sep-23-2021, 11:11 PM)SamHobbs Wrote: Yesterday I posted an alternative but I do not see it now. It can be modified to produce the same output if desired.

#import sys
import string
  
def checkPasswordStrength(password):

    if len(password) <= 6:
        print("Password must be at least 7 characters")
        return
    teststring = "luds"
    testlist = list(teststring)
    special_characters = '!@#$%^&*()'
    for letter in password :
        if letter.islower() :
            testlist[0] = 'X'
        elif letter.isupper() :
            testlist[1] = 'X'
        elif letter.isdigit() :
            testlist[2] = 'X'
        elif letter in special_characters :
            testlist[3] = 'X'
    test = ''.join(testlist)
    if test == "XXXX":
        print("Password is valid")
        return
    message = "Password is not valid; missing:"
    if testlist[0] == 'l':
        message += " lowercase letter ";
    if testlist[1] == 'u':
        message += " upper case letter ";
    if testlist[2] == 'd':
        message += " digit ";
    if testlist[3] == 's':
        message += " special character ";
    print(message)
 
 
checkPasswordStrength('Billycash')

Thank you for the effort. The algo is neat and efficient.
Reply
#9
Since people are submitting solutions now, I thought I might demonstrate a different approach. This is a pass/fail implementation with feedback. Get comfortable with Python exceptions. They are very useful.
def set_password(password):
    if len(password) < 7:
        raise ValueError("Password must be at least 7 characters")

    if not any(map(str.islower, password)):
        raise ValueError("Password must contain a lowercase letter")

    if not any(map(str.isupper, password)):
        raise ValueError("Password must contain an uppercase letter")

    if not any(map(str.isdigit, password)):
        raise ValueError("Password must contain a digit")

    if not (set(password) & set('!@#$%^&*()')):
        raise ValueError("Password must contain a special character")

    # Code that sets the password goes here

while password := input('Enter New Password: '):
    try:
        set_password(password)
        break
    except ValueError as msg:
        print(msg)
This computes a strength score.
def password_strength(password):
    strength = 0 if len(password) < 7 else 1

    if any(map(str.islower, password)):
        strength += 1

    if any(map(str.isupper, password)):
        strength += 1

    if any(map(str.isdigit, password)):
        strength += 1

    if set(password) & set('!@#$%^&*()'):
        strength += 1

    return strength

while password := input('Enter New Password: '):
    print(password_strength(password))
And if you love unreadable one-liners:
def valid_password(p):
    return all([len(p) > 0, any(map(str.islower, p)), any(map(str.isupper, p)), any(map(str.isdigit, p)), set(p) & set('!@#$%^&*()')])

while password := input('Enter New Password: '):
    print(valid_password(password))
It is good to know about any() and all(). To use any() or all() affectively it is also good to know about map() and list comprehensions.
Dexty likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable not defined in password checker DAS 4 4,509 Aug-27-2017, 08:40 PM
Last Post: ichabod801
  Password checker sammy2938 2 10,949 Jul-19-2017, 08:04 PM
Last Post: nilamo
  Email Checker with IMAPlib ronaldrios 1 3,762 Jun-23-2017, 04:03 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020