Repository navigation
Expand file tree
/
Copy pathsimpleP.cpp
More file actions
171 lines (152 loc) · 5.13 KB
/
Copy pathsimpleP.cpp
File metadata and controls
171 lines (152 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* simpleP — Simple Password Generator
* A lightweight terminal password generator.
* Licensed under GNU GPL v3.0 or later.
*/
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <cstdlib>
using namespace std;
// Word list for memorable passwords (common short words)
const vector<string> words = {
"apple", "blue", "cat", "dog", "sun", "moon", "star", "fish",
"bird", "tree", "book", "door", "fire", "gold", "hill", "ice",
"jazz", "king", "lion", "milk", "nose", "owl", "pen", "queen",
"rain", "snow", "top", "unit", "van", "wind", "yard", "zero"
};
/*
* getRandomBytes — reads random bytes from /dev/urandom.
* This is cryptographically secure and avoids the pwgen CVE-2013-4442 bug.
*/
void getRandomBytes(unsigned char *buf, size_t len) {
ifstream urandom("/dev/urandom", ios::binary);
urandom.read(reinterpret_cast<char *>(buf), len);
}
/*
* getRandomInt — returns a random integer in [0, max).
*/
int getRandomInt(int max) {
if (max <= 0) return 0;
unsigned char buf[4];
getRandomBytes(buf, 4);
unsigned int val = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
return val % max;
}
/*
* getRandomChar — returns a random character from the given set.
*/
char getRandomChar(const string &charset) {
return charset[getRandomInt(charset.length())];
}
/*
* generateMemorable — generates a memorable password like "Blue-House-42-Pine".
*/
string generateMemorable(int wordCount) {
string result;
for (int i = 0; i < wordCount; i++) {
string word = words[getRandomInt(words.size())];
// Capitalize first letter
word[0] = toupper(word[0]);
result += word;
if (i < wordCount - 1) result += "-";
}
// Add a random number at the end
result += "-" + to_string(getRandomInt(90) + 10);
return result;
}
/*
* generateStrong — generates a strong password with mixed characters.
*/
string generateStrong(int length) {
string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string lower = "abcdefghijklmnopqrstuvwxyz";
string digits = "0123456789";
string symbols = "!@#$%^&*()_+-=[]{}|;:,.<>?";
string all = upper + lower + digits + symbols;
string result;
// Ensure at least one of each type
result += getRandomChar(upper);
result += getRandomChar(lower);
result += getRandomChar(digits);
result += getRandomChar(symbols);
// Fill the rest randomly
for (int i = 4; i < length; i++) {
result += getRandomChar(all);
}
// Shuffle the result
for (int i = result.length() - 1; i > 0; i--) {
int j = getRandomInt(i + 1);
swap(result[i], result[j]);
}
return result;
}
/*
* generateAlphanum — generates an alphanumeric password (no symbols).
*/
string generateAlphanum(int length) {
string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
string result;
for (int i = 0; i < length; i++) {
result += getRandomChar(chars);
}
return result;
}
/*
* generatePin — generates a numeric PIN code.
*/
string generatePin(int length) {
string digits = "0123456789";
string result;
for (int i = 0; i < length; i++) {
result += getRandomChar(digits);
}
return result;
}
int main(int argc, char *argv[]) {
int length = 16; // default length for strong passwords
string mode = "strong"; // strong by default
// Parse arguments
for (int i = 1; i < argc; i++) {
string arg = argv[i];
if (arg == "--memorable") {
mode = "memorable";
length = 12;
} else if (arg == "--strong") {
mode = "strong";
} else if (arg == "--alphanum") {
mode = "alphanum";
} else if (arg == "--pin") {
mode = "pin";
length = 4;
} else {
try {
length = stoi(arg);
if (length < 4) length = 4;
if (length > 128) length = 128;
} catch (...) {
cout << "Usage: simplep [--strong|--memorable|--alphanum|--pin] [length]" << endl;
cout << " simplep strong password (16 chars)" << endl;
cout << " simplep 20 strong password (20 chars)" << endl;
cout << " simplep --memorable memorable password (4 words)" << endl;
cout << " simplep --alphanum alphanumeric only" << endl;
cout << " simplep --pin numeric PIN (4 digits)" << endl;
return 1;
}
}
}
string password;
if (mode == "memorable") {
int wordCount = max(3, length / 4);
password = generateMemorable(wordCount);
} else if (mode == "alphanum") {
password = generateAlphanum(length);
} else if (mode == "pin") {
password = generatePin(length);
} else {
password = generateStrong(length);
}
cout << password << endl;
return 0;
}