Generating secure passwords is crucial for protecting your online accounts and personal information. In this tutorial, we will walk you through a Python script that generates random passwords based on user-specified criteria, such as length, the inclusion of digits, special characters, and types of alphabets. This script uses the argparse module to handle command-line arguments and can be run directly from your terminal.
Prerequisites
Before we begin, ensure you have Python installed on your system. You can download it from python.org. Also make sure you have coding environment already set up on your computer. I'm using Visual Studio Code with Python Extension Pack installed.
Step 1: Import Necessary Modules
We start by importing the required Python modules:
stringandrandomfor generating the password.argparsefor handling command-line arguments.
import string
import random
import argparse
Step 2: Define Helper Functions
Next, we define helper functions to validate the user's input and to generate the password.
-
Validate Password Length:
This function ensures the password length is between 8 and 15 characters.def get_password_length(length: int) -> int: if 8 <= length <= 15: return length else: raise ValueError("Please enter a number between 8 and 15.") -
Validate Alphabet Choice:
This function checks if the user's choice for alphabets is valid.def get_alphabets_choice(choice: str) -> str: if choice in ['caps', 'small', 'mix', 'none']: return choice else: raise ValueError("Invalid choice for alphabets. Please choose caps, small, mix, or none.") -
Validate Digits Choice:
This function ensures the user's choice for including digits is valid.def get_digits_choice(choice: str) -> str: if choice in ['yes', 'no']: return choice else: raise ValueError("Invalid choice for digits. Please choose yes or no.") -
Validate Special Characters Choice:
This function checks if the user's choice for including special characters is valid.def get_special_characters_choice(choice: str) -> str: if choice in ['yes', 'no']: return choice else: raise ValueError("Invalid choice for special characters. Please choose yes or no.")
The raise ValueError statement in Python is used to generate an exception of type ValueError. An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. Specifically, a ValueError is raised when a function receives an argument of the right type but an inappropriate value, such as a number outside of an expected range.
In every function, when the validation fails, we have raised ValueError exception.
Step 3: Generate the Password
The core function of our script is generate_password, which creates the random password based on the user's criteria.
The logic is simple. First, we will build a character array by picking up the characters based on the options set by the User. Next, we will make random.choice to pick characters randomly from this array and will join the new random character derived with the previous one, until the length of joined characters is less than the desired password length specified by the User.
Let's do it.
def generate_password(length: int, alphabets: str, digits: str, special_chars: str) -> str:
password_chars = ''
if alphabets == 'caps':
password_chars += string.ascii_uppercase
elif alphabets == 'small':
password_chars += string.ascii_lowercase
elif alphabets == 'mix':
password_chars += string.ascii_letters
if digits == 'yes':
password_chars += string.digits
if special_chars == 'yes':
password_chars += string.punctuation
if not password_chars:
raise ValueError("No characters selected to generate password.")
password = ''.join(random.choice(password_chars) for _ in range(length))
return password
Let me walk you through the code of this function.
-
Initialize
password_chars:
We start with an empty stringpassword_charswhich will hold all possible characters that can be used in the password. -
Add Alphabet Characters:
Depending on the user's choice (caps,small,mix), we append the corresponding alphabet characters topassword_chars.caps: Adds uppercase letters.small: Adds lowercase letters.mix: Adds both uppercase and lowercase letters.
-
Add Digit Characters:
If the user choseyesfor digits, we add numeric digits (0-9) topassword_chars. -
Add Special Characters:
If the user choseyesfor special characters, we add punctuation characters (e.g.,!@#$%^&*()) topassword_chars. -
Check for Valid Characters:
Ifpassword_charsis still empty after processing all choices, we raise an error because there are no characters to generate the password from. -
Generate the Password:
Usingrandom.choice(), we randomly select characters frompassword_charsto form a password of the desired length. The resulting characters are joined together to form the final password.
Step 4: Handle Command-Line Arguments
We use argparse to handle the command-line arguments and call the helper functions to validate the inputs. argparse is a module in Python's standard library used to parse command-line arguments. It provides a way to handle user inputs from the command line, allowing you to write flexible and user-friendly command-line interfaces for your programs.
def main() -> None:
parser = argparse.ArgumentParser(description='Generate a random password.')
parser.add_argument('--length', type=int, default=8, help='The length of the password (between 8 and 15)')
parser.add_argument('--alphabets', type=str, choices=['caps', 'small', 'mix', 'none'], default='mix', help='Alphabets: caps, small, mix, none')
parser.add_argument('--digits', type=str, choices=['yes', 'no'], default='yes', help='Digits: yes, no')
parser.add_argument('--special_chars', type=str, choices=['yes', 'no'], default='yes', help='Special Characters: yes, no')
args = parser.parse_args()
try:
length = get_password_length(args.length)
alphabets = get_alphabets_choice(args.alphabets)
digits = get_digits_choice(args.digits)
special_chars = get_special_characters_choice(args.special_chars)
password = generate_password(length, alphabets, digits, special_chars)
print(f"Generated Password: {password}")
except ValueError as e:
print(e)
-
Set Up Argument Parser:
We create anArgumentParserobject and add four arguments:--length: The desired length of the password (default is 8).--alphabets: The type of alphabets to include (default ismix).--digits: Whether to include digits (default isyes).--special_chars: Whether to include special characters (default isyes).
-
Parse Arguments:
Theparser.parse_args()method parses the command-line arguments and stores them inargs. -
Validate Inputs:
We call our helper functions to validate the user's inputs for length, alphabets, digits, and special characters. These functions will raise aValueErrorif any input is invalid. -
Generate and Print Password:
If all inputs are valid, we callgenerate_passwordto create the password and print it. If there is aValueError, we catch it and print the error message.
Step 5: Call main() inside if __name__ == "__main__
if __name__ == "__main__":
main()
It is a common Python idiom used to ensure that certain code is only executed when the script is run directly, and not when it is imported as a module in another script.
__name__is a special built-in variable in Python that represents the name of the current module.- When a Python file is run directly, the
__name__variable is set to"__main__". - When a Python file is imported as a module in another script, the
__name__variable is set to the name of the file (e.g.,"password_generator"if the file is namedpassword_generator.py). - Finally, by placing
main()function call inside theif __name__ == "__main__":block, we ensure thatmain()is only executed when the script is run directly, and not when it is imported.
Here is the complete code:
import string
import random
import argparse
def get_password_length(length: int) -> int:
if 8 <= length <= 15:
return length
else:
raise ValueError("Please enter a number between 8 and 15.")
def get_alphabets_choice(choice: str) -> str:
if choice in ['caps', 'small', 'mix', 'none']:
return choice
else:
raise ValueError("Invalid choice for alphabets. Please choose caps, small, mix, or none.")
def get_digits_choice(choice: str) -> str:
if choice in ['yes', 'no']:
return choice
else:
raise ValueError("Invalid choice for digits. Please choose yes or no.")
def get_special_characters_choice(choice: str) -> str:
if choice in ['yes', 'no']:
return choice
else:
raise ValueError("Invalid choice for special characters. Please choose yes or no.")
def generate_password(length: int, alphabets: str, digits: str, special_chars: str) -> str:
password_chars = ''
if alphabets == 'caps':
password_chars += string.ascii_uppercase
elif alphabets == 'small':
password_chars += string.ascii_lowercase
elif alphabets == 'mix':
password_chars += string.ascii_letters
if digits == 'yes':
password_chars += string.digits
if special_chars == 'yes':
password_chars += string.punctuation
if not password_chars:
raise ValueError("No characters selected to generate password.")
password = ''.join(random.choice(password_chars) for _ in range(length))
return password
def main() -> None:
parser = argparse.ArgumentParser(description='Generate a random password.')
parser.add_argument('--length', type=int, default=8, help='The length of the password (between 8 and 15)')
parser.add_argument('--alphabets', type=str, choices=['caps', 'small', 'mix', 'none'], default='mix', help='Alphabets: caps, small, mix, none')
parser.add_argument('--digits', type=str, choices=['yes', 'no'], default='yes', help='Digits: yes, no')
parser.add_argument('--special_chars', type=str, choices=['yes', 'no'], default='yes', help='Special Characters: yes, no')
args = parser.parse_args()
try:
length = get_password_length(args.length)
alphabets = get_alphabets_choice(args.alphabets)
digits = get_digits_choice(args.digits)
special_chars = get_special_characters_choice(args.special_chars)
password = generate_password(length, alphabets, digits, special_chars)
print(f"Generated Password: {password}")
except ValueError as e:
print(e)
if __name__ == "__main__":
main()
Run the Script
To generate a password, open your terminal and run the script with the desired options. For example:
python password_generator.py --length 12 --alphabets mix --digits yes --special_chars yes
This command generates a 12-character password containing a mix of uppercase and lowercase letters, digits, and special characters.
Conclusion
This Python script is a simple yet powerful tool for generating random passwords. By customizing the length, alphabet type, and inclusion of digits and special characters, you can create strong and unique passwords to enhance your security. Happy coding!
