Skip to content
API Documentation
BastionGuard™
PasswordGenerator.cpp
Go to the documentation of this file.
1/*
2 * BastionGuard™
3 * Copyright (C) 2025–2026 Calogero Scarnà
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 *
17 * BastionGuard™ is a trademark of Calogero Scarnà.
18 * The BastionGuard™ name and branding are not licensed under the GPL.
19 */
20
21#include "PasswordGenerator.hpp"
22
23#include <random>
24#include <stdexcept>
25#include <vector>
26#include <algorithm>
27
28char PasswordGenerator::randomFrom(const std::string& charset) {
29 if (charset.empty()) {
30 throw std::runtime_error("Charset vuoto");
31 }
32
33 static thread_local std::random_device rd;
34 static thread_local std::mt19937 gen(rd());
35
36 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
37 return charset[dist(gen)];
38}
39
40std::string PasswordGenerator::generate(std::size_t length,
41 bool useUpper,
42 bool useLower,
43 bool useDigits,
44 bool useSymbols) {
45 const std::string upper = "ABCDEFGHJKLMNPQRSTUVWXYZ";
46 const std::string lower = "abcdefghijkmnopqrstuvwxyz";
47 const std::string digits = "23456789";
48 const std::string symbols = "!@#$%^&*()-_=+[]{}.?";
49
50 std::vector<std::string> enabledSets;
51 std::string allChars;
52
53 if (useUpper) {
54 enabledSets.push_back(upper);
55 allChars += upper;
56 }
57 if (useLower) {
58 enabledSets.push_back(lower);
59 allChars += lower;
60 }
61 if (useDigits) {
62 enabledSets.push_back(digits);
63 allChars += digits;
64 }
65 if (useSymbols) {
66 enabledSets.push_back(symbols);
67 allChars += symbols;
68 }
69
70 if (enabledSets.empty()) {
71 throw std::runtime_error("Nessun set di caratteri abilitato");
72 }
73
74 if (length < enabledSets.size()) {
75 length = enabledSets.size();
76 }
77
78 std::string password;
79 password.reserve(length);
80
81 for (const auto& set : enabledSets) {
82 password.push_back(randomFrom(set));
83 }
84
85 while (password.size() < length) {
86 password.push_back(randomFrom(allChars));
87 }
88
89 static thread_local std::random_device rd;
90 static thread_local std::mt19937 gen(rd());
91 std::shuffle(password.begin(), password.end(), gen);
92
93 return password;
94}
static char randomFrom(const std::string &charset)
static std::string generate(std::size_t length=20, bool useUpper=true, bool useLower=true, bool useDigits=true, bool useSymbols=true)