Reputation: 77
I wrote this to generate a random password:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
string read(string value) { //read value
ifstream input;
int olength;
string line = "", output = "";
size_t pos;
bool a = true;
int i = 0;
input.open("pg_options.txt");
if (!input.is_open()) {
cout << "pg_options.txt missing.";
return "error";
}
while (getline(input, line)) {
pos = line.find(value);
if (pos != string::npos) {
while (a == true) {
if (line[i] == '=') {
i++;
break;
}
else {
i++;
}
}
olength = line.length() - value.length() - 1;
for (int i2 = 0; i2 < olength; i2++) {
output += line[i];
i++;
}
}
}
input.close();
return output;
}
char randupper() { //generate random upper case character
char uppercase[26] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
int i = rand() % 26;
return uppercase[i];
}
char randlower() { //generate random lower case character
char lowercase[26] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
int i = rand() % 26;
return lowercase[i];
}
char randspecial() { //generate random special character
char special[7] = { '!', '#', '$', '%', '&', '*', '?' };
int i = rand() % 7;
return special[i];
}
char randnumbers() { //generate random number
char numbers[10] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
int i = rand() % 10;
return numbers[i];
}
void generate() { //generate the password
string output = "";
int i1=0, digits = 0, upper = 0, lower = 0, special = 0, numbers = 0;
digits = stoi(read("digits")); //get digits
if (read("include_upper_case") == "true") { //determine number of upper case characters
upper = rand() % (digits / 2) + 1;
digits -= upper;
}
if (read("include_lower_case") == "true") {
lower = rand() % (digits / 2) + 1;
digits -= lower;
}
if (read("include_special_characters") == "true") {
special = rand() % (digits / 2) + 1;
digits -= special;
}
if (read("include_numbers") == "true") {
numbers = digits;
}
else { //if numbers not included
if (read("include_upper_case") == "true") {
upper += digits;
}
else if (read("include_lower_case") == "true") {
lower += digits;
}
else if (read("include_special_characters") == "true") {
special += digits;
}
else {
cout << "error generating, please check your options.";
return;
}
}
for (int i = 0; i < stoi(read("digits")); i++) {
i1 = rand() % 4;
if (i1 == 0) { //if uppercase
if (upper > 0) {
output += randupper();
upper--;
}
else {
i--;
}
}
else if (i1 == 1) {
if (lower > 0) {
output += randlower();
lower--;
}
else {
i--;
}
}
else if (i1 == 2) {
if (special > 0) {
output += randspecial();
special--;
}
else {
i--;
}
}
else if (i1 == 3) {
if (numbers > 0) {
output += randnumbers();
numbers--;
}
else {
i--;
}
}
}
cout << output;
}
int main() {
generate();
return 0;
}
pg_options.txt:
include_special_characters=true
include_upper_case=true
include_lower_case=true
include_numbers=true
digits=10
However, it generates the same thing every time it runs, that is HM*nfx375g
, so it has same sequence of random numbers. (in generate(), upper is always 2, lower is always 4, special is always 1, numbers is always 3...) Is there a function that can generate different random numbers every time?
Upvotes: 2
Views: 913
Reputation: 12849
Random generators need to be seeded to have a random starting point. In your case, it needs to be done by calling srand()
before using rand()
, for example:
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0)); // <-- add this!
generate();
return 0;
}
However, the preferred C++ way of generating random numbers is to use the functions and types available in the <random>
header file. srand()
and rand()
are basically a leftover from C.
See this example:
#include <iostream>
#include <vector>
#include <string>
#include <random>
// get 'entropy' from device that generates random numbers itself
// to seed a mersenne twister (pseudo) random generator
static std::mt19937 generator(std::random_device{}());
char random_lowercase_char()
{
static std::uniform_int_distribution<std::size_t> distribution('a', 'z');
return static_cast<char>(distribution(generator));
}
char random_uppercase_char()
{
static std::uniform_int_distribution<std::size_t> distribution('A', 'Z');
return static_cast<char>(distribution(generator));
}
char random_number_char()
{
static std::uniform_int_distribution<std::size_t> distribution('0', '9');
return static_cast<char>(distribution(generator));
}
char random_special_char()
{
static std::vector<char> specials{ '!', '#', '$', '%', '&', '*', '?' };
static std::uniform_int_distribution<std::size_t> distribution(0, specials.size()-1);
auto index = (distribution(generator));
return specials[index];
}
int main()
{
for (int i = 0; i < 40; i++)
{
std::cout << random_lowercase_char();
std::cout << random_uppercase_char();
std::cout << random_number_char();
std::cout << random_special_char();
std::cout << std::endl;
}
}
Upvotes: 10
Reputation: 31
First add the <ctime>
library
Then use srand(time(NULL));
before generating any random numbers with rand()
.
Upvotes: 3