I have written an extremely simple program that has rudimentary password generation with selective character types (symbols, numbers, uppercase, and lowercase). Here is the C++ code:
#include <iostream>
#include <cstdlib>
#include <ctime>
inline bool getOptions(const std::string & option);
inline long long unsigned getLength();
int main(){
bool syms = getOptions("Symbols"),
nums = getOptions("Numbers"),
lower = getOptions("Lowercase Chars"),
upper = getOptions("Uppercase Chars");
if(!(syms || nums || lower || upper)){
std::cout << "ERR: No options selected.";
return -1;
}
const std::string str_syms = "`~!@#$%%^&*()-=_+[]{}\\|;:\'\",<.>/\?",
str_nums = "1234567890",
str_lower = "abcdefghijklmnopqrstuvwxyz",
str_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string allowedChars;
if(syms) allowedChars += str_syms;
if(nums) allowedChars += str_nums;
if(lower) allowedChars += str_lower;
if(upper) allowedChars += str_upper;
long long unsigned passLength = getLength();
std::string password;
srand(time(NULL));
for(long long unsigned i = 0; i < passLength; ++i){
password += allowedChars[std::rand() % allowedChars.length()];
}
std::cout << password << '\n';
return 0;
}
inline bool getOptions(const std::string & option){
std::string choice;
while(true) {
std::cout << option + " (y/N): ";
std::getline(std::cin, choice);
if(tolower(choice[0]) == 'y') {
return true;
} else if(tolower(choice[0]) == 'n') {
return false;
}
}
}
inline long long unsigned getLength(){
std::string str_passLength;
long long unsigned passLength;
while(true) {
std::cout << "Password Length: ";
std::getline(std::cin, str_passLength);
try{
passLength = std::stoll(str_passLength);
} catch(const std::invalid_argument & e){
std::cerr << "\n\tERR: Invalid argument.\n";
} catch(const std::out_of_range & e){
std::cerr << "\n\tERR: Out of range (long long unsigned).\n";
} catch(...){
std::cerr << "\n\tERR: Unknown, something messed up.\n";
}
if(passLength > 0){
return passLength;
}
}
}
Then, I recreated the program in Python3, just for practice since I am learning the syntax of Python.
#!/usr/bin/python
from random import randint
def getOptions(option):
choice = ""
while True:
print("{} (y/N): ".format(option), end="")
choice = input()
if choice[0].lower() == 'y':
return True
elif choice[0].lower() == 'n':
return False
def getLength():
str_passLength = ""
passlength = 0
while True:
str_passLength = input("Password Length: ")
try:
passlength = int(str_passLength)
except:
print("\n\tERR: Invalid.\n")
if passlength > 0:
return passlength
def main():
syms = getOptions("Symbols")
nums = getOptions("Numbers")
lower = getOptions("Lowercase Chars")
upper = getOptions("Uppercase Chars")
if not(syms or nums or lower or upper):
print("ERR: No options selected.")
return -1
str_syms = "`~!@#$%%^&*()-=_+[]{}\\|;:\'\",<.>/\?"
str_nums = "1234567890"
str_lower = "abcdefghijklmnopqrstuvwxyz"
str_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
allowedChars = ""
if syms: allowedChars += str_syms
if nums: allowedChars += str_nums
if lower: allowedChars += str_lower
if upper: allowedChars += str_upper
passLength = getLength()
password = ""
for i in range(passLength):
password += allowedChars[randint(0, len(allowedChars) - 1)]
print(password, '\n')
main()
I understand that this program is so short that all realistically long password lengths will run almost instantaneously on all modern machines.
However, I wish to improve its readability, logic, and most importantly its brevity. How can I do so?