From 5469c2563e40ffef33da2eb11852c5e8068e841d Mon Sep 17 00:00:00 2001 From: Pronoy Mandal Date: Thu, 27 Oct 2022 22:47:25 +0530 Subject: [PATCH] Update check_strong_password.py 1. Change the functional concept that a strong password checker must return a boolean indicating whether the password is strong or not AND not a response string, the choice of which can be subjective. 2. Add another alternative checker which has a theoretical time complexity better than the original one. 3. Rectify the length checking to adhere to the minimum length as opposed to a hardcoded value. 4. Optimise to make more Pythonic expressions and returns. 5. Add comments wherever necessary. --- other/check_strong_password.py | 81 +++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/other/check_strong_password.py b/other/check_strong_password.py index 95bb327addf4..04766509870a 100644 --- a/other/check_strong_password.py +++ b/other/check_strong_password.py @@ -5,40 +5,81 @@ from string import ascii_lowercase, ascii_uppercase, digits, punctuation -def strong_password_detector(password: str, min_length: int = 8) -> str: +def is_strong_password(password: str, min_length: int = 8) -> bool: """ - >>> strong_password_detector('Hwea7$2!') - 'This is a strong Password' + >>> is_strong_password('Hwea7$2!') + True - >>> strong_password_detector('Sh0r1') - 'Your Password must be at least 8 characters long' + >>> is_strong_password('Sh0r1') + False - >>> strong_password_detector('Hello123') - 'Password should contain UPPERCASE, lowercase, numbers, special characters' + >>> is_strong_password('Hello123') + False - >>> strong_password_detector('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1') - 'This is a strong Password' + >>> is_strong_password('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1') + True - >>> strong_password_detector(0) - 'Your Password must be at least 8 characters long' + >>> is_strong_password(0) + False """ - if len(str(password)) < 8: - return "Your Password must be at least 8 characters long" + # Rudimentary check when an int or float type is used as a password + # having no. of digits less than min_length + if len(str(password)) < min_length: + return False + # Boolean character flags which are set on encountering a character of + # a given type upper = any(char in ascii_uppercase for char in password) lower = any(char in ascii_lowercase for char in password) num = any(char in digits for char in password) spec_char = any(char in punctuation for char in password) - if upper and lower and num and spec_char: - return "This is a strong Password" + return upper and lower and num and spec_char - else: - return ( - "Password should contain UPPERCASE, lowercase, " - "numbers, special characters" - ) + +def is_strong_password_2(password: str, min_length: int = 8) -> bool: + """ + >>> is_strong_password_2('Hwea7$2!') + True + + >>> is_strong_password_2('Sh0r1') + False + + >>> is_strong_password_2('Hello123') + False + + >>> is_strong_password_2('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1') + True + + >>> is_strong_password_2(0) + False + """ + # Initialise boolean flags which toggle when the first occurrence of a + # type is encountered + upper = lower = num = spec_char = False + + # Rudimentary check when an int or float type is used as a password + # having no. of digits less than min_length + if len(str(password)) < min_length: + return False + + # Parse each of the characters and check whether they are within the + # concerned lexicographic boundaries + # Toggle respective flags when you encounter a character type + # Avoid the check when the concerned character flag is already set + + for char in password: + if not num and "0" <= char <= "9": + num = True + elif not upper and "A" <= char <= "Z": + upper = True + elif not lower and "a" <= char <= "z": + lower = True + elif not spec_char and char in punctuation: + spec_char = True + + return num and spec_char and upper and lower if __name__ == "__main__":