#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <stdexcept>
#include <random>
class Args
{
private:
std::vector<std::string> args;
public:
Args(int argc, char *argv[])
{
for (int i = 1; i < argc; ++i)
args.push_back(static_cast<std::string>(argv[i]));
}
bool has_flag(const std::string &flag) const
{
if (std::find(args.begin(), args.end(), flag) != args.end())
return true;
return false;
}
std::string get_val(const std::string &flag, const std::string &def_val = "") const
{
auto it_flag = std::find(args.begin(), args.end(), flag);
if (it_flag != args.end() && ++it_flag != args.end())
{
if ((*it_flag)[0] != '-')
return *it_flag;
}
return def_val;
}
};
void help()
{
std::cout << "Password Generator CLI v1.0.0\n\n"
"Usage: password-gen [options]\n\n"
"Options:\n"
" -h, --help Show this help message\n"
" -l, --length NUM Password length (default: 12)\n"
" -c, --count NUM Number of passwords to generate (default: 1)\n"
" -d, --digits Include digits (0-9)\n"
" -u, --uppercase Include uppercase letters (A-Z)\n"
" -s, --special Include special characters (!@#$%^&*)\n"
" -e, --exclude Exclude ambiguous characters (l, 1, O, 0)\n";
}
template <typename T>
void display(const std::vector<T> &vec)
{
for (const auto &el : vec)
std::cout << el << std::endl;
}
int main(int argc, char *argv[])
{
std::random_device rd;
std::mt19937 gen(rd());
Args args(argc, argv);
std::string lower = "abcdefghijklmnopqrstuvwxyz";
std::string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string digits = "0123456789";
const std::string special = "!@#$%^&*";
if (args.has_flag("-h") || args.has_flag("--help"))
{
help();
return 0;
}
if(args.has_flag("-e") || args.has_flag("--exclude"))
{
lower.erase(std::find(lower.begin(), lower.end(), 'l'));
lower.erase(std::find(lower.begin(), lower.end(), 'o'));
}
std::uniform_int_distribution<> dist(0, 25);
int length = 12, count = 1;
try
{
//parsing -l(--length) flag
if (args.has_flag("-l"))
length = std::stoi(args.get_val("-l"));
else if (args.has_flag("--length"))
length = std::stoi(args.get_val("-length"));
if (length <= 2)
throw std::out_of_range("Invalid pass size, should be more than 2");
//parsing -c(--count) flag
if (args.has_flag("-c"))
count = std::stoi(args.get_val("-c"));
else if (args.has_flag("--count"))
count = std::stoi(args.get_val("--count"));
if (count < 0)
throw std::out_of_range("Invalid pass count, should be more or equal to 1");
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
std::vector<std::string> result {};
for(int i = 0; i < count; ++i)
{
std::string pass = "";
for(int j = 0; j < length; ++j)
pass += lower[dist(gen)];
result.push_back(pass);
}
std::cout << "===";
if(count > 1) std::cout << count << " generated passes===" << std::endl;
else std::cout << count << " generated pass===" << std::endl;
display(result);
return 0;
}