generate a random string in C++11? [duplicate] - c++

This question already has answers here:
How do I create a random alpha-numeric string in C++?
(20 answers)
Closed 4 years ago.
I need help with generating a random string using C++11.
I don't know how to continue with that, if you can help me please.
#include <random>
char * random_string()
{
static const char alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static const MAX_LEN = 32; //MAX LENGTH OF THE NEW CHAR RETURNED
int stringLength = sizeof(alphabet)/sizeof(alphabet[0]);
for (int i = 0; i<=MAX_LEN;i++)
{
//now i don't know what i need to do help!
}
static const char test[MAX_LEN];
return test;
}

Return a std::string rather than a raw char *. Populate the string as needed to start, and then shuffle it.
For example;
#include <random>
#include <string>
std::string random_string()
{
std::string str("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
std::random_device rd;
std::mt19937 generator(rd());
std::shuffle(str.begin(), str.end(), generator);
return str.substr(0, 32); // assumes 32 < number of characters in str
}
If you really need to extract a raw const char * from a std::string use its c_str() member function.
int main()
{
std::string rstr = random_string();
some_func_that_needs_const_char_pointer(rstr.c_str());
}

Using Mersene Twister 19937 generator and Uniform discrete distribution you can generate random strings from ranges like "A-Z","a-z" or "0-9" easily.
#include <iostream>
#include <string>
#include <random>
using namespace std;
int main() {
mt19937 generator{random_device{}()};
//modify range according to your need "A-Z","a-z" or "0-9" or whatever you need.
uniform_int_distribution<int> distribution{'a', 'z'};
auto generate_len = 6; //modify length according to your need
string rand_str(generate_len, '\0');
for(auto& dis: rand_str)
dis = distribution(generator);
cout << "Random string generated : " << rand_str << endl;
}

#include <random>
using namespace std;
string generate(int max_length){
string possible_characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
random_device rd;
mt19937 engine(rd());
uniform_int_distribution<> dist(0, possible_characters.size()-1);
string ret = "";
for(int i = 0; i < max_length; i++){
int random_index = dist(engine); //get index between 0 and possible_characters.size()-1
ret += possible_characters[random_index];
}
return ret;
}

Related

How to bind numbers together into an integer without addition?

For example:
If I end up with multiple digits and all of those numbers are generated randomly (1-9) up to 7 digits total and I want them all to end up as a whole integer, how do I go by doing this?
Here is something I have tried:
static void generate_key(std::map<std::string, int>& key, std::string c_user)
{
unsigned int hold[7]{}; // will hold all the random integers seperate to add onto final
int *final = new int; // will store a complete 7 digit integer here later on
for (int i = 0; i < 7; i++)
{
unsigned int num = rand() % 9;
hold[i] = num;
}
*final = hold[0] + hold[1] + hold[2] + hold[3]; // I know this sums everything but how do I get it to just add all the numbers into a single integer?!
key.emplace(c_user, final);
std::cout << "Key created: " << *final << '\n';
delete final;
}
Hold all integers seperate from eachother:
unsigned int hold[7]{};
Create random digits:
for (int i = 0; i < 7; i++)
{
unsigned int num = rand() % 9;
hold[i] = num;
}
Store and add all integers into *final integer
int *final = new int;
I want to generate a 7 digit key and each of every single digit is randomized. I then want to add them all up to make a whole integer that gets put into a map where a string has already been created and that key will represent the string. Do you get what I'm saying here? Sorry if my explanation is terrible I'm just too lost here..
Here is the full code if thats helpful:
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <stdlib.h>
class Account
{
private:
std::string username;
std::string password;
public:
Account(std::string username, std::string password)
{
this->username = username;
this->password = password;
}
~Account() {};
std::string get_username()const { return username; }
std::string get_password()const { return password; }
};
static void create_account(std::string user, std::string pass, std::vector<Account> &acc)
{
Account *account = new Account(user, pass);
acc.push_back(*account);
delete account;
}
static void generate_key(std::map<std::string, int>& key, std::string c_user)
{
unsigned int hold[7]{};
int *final = new int;
for (int i = 0; i < 7; i++)
{
unsigned int num = rand() % 9;
hold[i] = num;
}
*final = hold[0] + hold[1] + hold[2] + hold[3];
key.emplace(c_user, final);
std::cout << "Key created: " << *final << '\n';
delete final;
}
std::vector<Account> accounts;
std::map<std::string, int> keys;
int main()
{
srand(time(NULL));
create_account("random", "triathlon", accounts);
generate_key(keys, accounts[0].get_username());
return 0;
}
static void create_account(std::string, std::string, std::vector<Account> &acc);
static void generate_key(std::map<std::string, int>&, std::string);
If you want to generate a 7 digit number where all of the digits are unique, then you can store the valid digits in a vector and then shuffle that vector and take the first 7 elements as the digit to make the number with. That could be done like:
std::vector<char> digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
std::random_device rd;
std::mt19937 g(rd());
std::suffle(digits.being(), digits.end(), g);
std::string number{digits.begin(), digits.begin() + 7}
and now number is a 7 digit string where each digit only appears once. If you want to not have a leading zero, then you would need to check if the first element is a zero and if so, shuffle again or just takes elements 1 through 7.
If you just want to generate a 7 digit number, but you don't care if there are duplicate digits, then you can do that with a std::string and a simple for loop like:
std::random_device rd;
std::mt19937 g(rd());
std::uniform_int_distribution<> dist(0, 9);
std::string number;
for (int i = 0; i < 7; ++i)
{
number.push_back('0' + dist(g))
}
If you just want a random seven digit number with unique digits you can generate that directly using the typical random shuffle algorithm where you generate a random index into an array take that item, swap the back of the array with it, and pop back of the array.
I forget what this algorithm is called.
In your case you only need to do seven iterations starting with the nine digits. Code below:
#include <vector>
#include <array>
#include <algorithm>
#include <iostream>
int remove_rnd_item( std::vector<int>& digits ) {
int n = rand() % digits.size(); // should use a better RNG...
int rnd_digit = digits[n];
//swap with the last digit and pop...
std::swap(digits[n], digits.back());
digits.pop_back();
return rnd_digit;
}
int random_seven_digit_number_with_unique_digits() {
std::vector<int> digits = { 0,1,2,3,4,5,6,7,8,9 };
std::array<int, 7> rnd_digits;
std::generate(rnd_digits.begin(), rnd_digits.end(),
[&digits]() {
return remove_rnd_item(digits);
}
);
// convert the digits vector to a single int, if that is what you want
int tens_place = 1;
int val = 0;
for (auto digit : rnd_digits) {
val += tens_place * digit;
tens_place *= 10;
}
return val;
}
int main() {
for (int i = 0; i < 10; ++i) {
std::cout << random_seven_digit_number_with_unique_digits() << "\n";
}
}
I assume that the requirement to have all unique digits in the customer ID is erroneous.
To get a random 7-digit number you only need:
#include <random>
#include <iostream>
int main()
{
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> distrib(0, 9'999'999);
std::cout << distrib(gen) << std::endl;
}
If you want to avoid leading zeroes, use distrib(1'000'000, 9'999'999);
Weeee! Hi!.I'm a beginner too!. and yeah. I think you can do that like this!.
int boop(){
int ding=1000000;
int a[7]={1,4,6,3,4,2,4};
int re=0;
for(int i=0;i<7;i++){
re+=a[i]*ding;
ding/=10;
}
return re;
}
or just make your own function to make a random number ranging from 0 to 1. and multiply it with 9999999. (kinda recommended).
#include <iostream>
#include <math.h>
float boop(int seed){
return abs(sin( cos(seed*3972)*38472));
}
int main(){
float f=boop(34)*9999999;
std::cout<<(int)f;
return 0;
}

What is the most efficient way to generate random strings in C++?

I need to generate random strings efficiently. In the following, you will see my first try. I compiled the code with gcc and -O3 optimization level. It takes 18.5 seconds to generate 10^7 random strings of length 64:
#include <iostream>
#include <random>
#include <algorithm>
std::string chars {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%^&*()`~-_=+[{]{|;:'\",<.>/?"};
std::random_device rd;
std::mt19937 generator(rd());
std::string rand_str (int length) {
std::string output (chars);
std::shuffle(output.begin(), output.end(), generator);
return output.substr(0, length);
}
int main() {
std::string str;
for (long i=0; i<10000000; ++i)
str = rand_str (64);
}
I checked std::sample in c++17 and it is not faster than the above method. In addition, it will not change the order of characters and so it is not really random.
Edit: The std::shuffle is not a good choice, since, it will not allow duplicates. Based on comments I modified the code. This time it takes more than 9 minutes for 10^7 random numbers.
std::string rand_str (size_t length) {
const size_t char_size = chars.size();
std::uniform_int_distribution<> random_int (0, char_size - 1);
std::string output;
for (size_t i=0; i<length; ++i)
output.push_back(chars[random_int(generator)]);
return output;
}
Question
Are there more efficient ways to do this in modern C++?
I appreciate any suggestions to improve the code.
#include <iostream>
#include <random>
#include <algorithm>
#include <chrono>
std::string chars {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%^&*()`~-_=+[{]{|;:'\",<.>/?"};
std::random_device rd;
std::mt19937 generator(rd());
std::string rand_str(int length) {
std::string output;
output.reserve(length);
while(length>0)
{
auto randNumb = generator();
while(randNumb > 93 && length--)
{
output.push_back(chars[randNumb%93]);
randNumb/=93;
}
}
return output;
}
int main() {
auto startTP = std::chrono::system_clock::now();
std::string rand_bytes;
for (long i=0; i<10000000; ++i)
rand_bytes = std::move(rand_str(64));
auto endTP = std::chrono::system_clock::now();
std::cout << "This took: " << std::chrono::duration_cast<std::chrono::microseconds>(endTP-startTP).count() << std::endl;
}
This takes around 3 seconds on my machine. The trick is to call the random number generator as little as possible and to allocate the memory only once.
What I'm doing is converting randNumber from base 10 to base 93(the length of chars). After that im using every base 93 digit as a different random number. This provides around 5 numbers per generated random number.

How to do Random Array with Strings?

I hope this is a very simple question, but how can you random a string within a array
For example, for vaules ill do this
`
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
srand ( time(NULL) ); //initialize the random seed
const char arrayNum[4] = {'1', '3', '7', '9'};
int RandIndex = rand() % 4;
int RandIndex_2 = rand() % 4;
int RandIndex_3 = rand() % 4;
int RandIndex_4 = rand() % 4; //generates a random number between 0 and 3
cout << arrayNum[RandIndex] << endl;;
system("PAUSE");
return 0;
} `
how can i apply this if there is string within the arraynum
I have come across something like this in my serach for an answer though
std::string textArray[4] = {"Cake", "Toast", "Butter", "Jelly"};
but all I come across is a hex answer which does not change on it's own. so therefore I am going to assume it is probably not even randomized.
You could use std::random_shuffle
#include <string>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
int main() {
std::srand(std::time(0));
std::string str = "123456212";
std::random_shuffle(str.begin(),str.end());
std::cout << str;
}
Possible output: 412536212
If you're using C++11, you can do the same with C-Style arrays like so:
int main() {
std::srand(std::time(0));
std::string str[4] = {"Cake", "Toast", "Butter", "Jelly"};
std::random_shuffle(std::begin(str),std::end(str));
for(auto& i : str)
std::cout << i << '\n';
}
Or if you're lacking a C++11 compiler you can do the alternative:
int main() {
std::srand(std::time(0));
std::string str[4] = {"Cake", "Toast", "Butter", "Jelly"};
std::random_shuffle(str, str + sizeof(str)/sizeof(str[0]));
for(size_t i = 0; i < 4; ++i)
std::cout << str[i] << '\n';
}

random function in C++

Is there a function that generates k random numbers within a specified range.
For example I want 5 random numbers between 0 to 100, with or without replacement.
You could use std::generate_n with either rand() or a generator from the new C++11 random number generators.
There is the Boost library, which you can use to generate random numbers, for example.
The following code generates 5 random numbers from [0, 100] with replacement:
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
std::vector<int> result;
for (int i = 0; i < numWantedNumbers; ++i)
result.push_back(distribution(generator));
}
If you want to generate the numbers without replacement, simply check if they are
still available:
#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
std::vector<int> result;
while (result.size() < numWantedNumbers)
{
int number = distribution(generator);
if (std::find(result.begin(), result.end(), number) == result.end())
result.push_back(number);
}
}
Note: The rejection sampling in the example without replacement has the obvious drawback that longer vectors are quite difficult to create. Just try to draw 99 out
of 100 numbers, to see what I mean (or even better draw 9999 out of 10000). If this
is a problem, I would suggest to create a random permutation of all possible numbers
and then cut the vector at the requested size:
#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
// Generate a vector with all possible numbers and shuffle it.
std::vector<int> result;
for (int i = 0; i <= 100; ++i)
result.push_back(i);
for (int i = 0; i <= 100; ++i)
{
int x = distribution(generator);
std::swap(result[i], result[x]);
}
// Truncate to the requested size.
result.resize(numWantedNumbers);
}
Edit based on suggestion by juanchopanza:
In C++11 manner, the last variant would look like this
#include <algorithm>
#include <random>
#include <vector>
const int numWantedNumbers = 5;
int main()
{
std::random_device device;
std::mt19937 generator(device());
std::uniform_int_distribution<> distribution(0, 100);
// Generate a vector with all possible numbers and shuffle it.
std::vector<int> result;
for (int i = 0; i <= 100; ++i)
result.push_back(i);
std::random_shuffle(result.begin(), result.end());
// Truncate to the requested size.
result.resize(numWantedNumbers);
}
g++-4.6 compiles it happily, if you add the -std=c++0x switch.
Edit: Make use of std::random_shuffle() (tanks to James Kanze).
Yes there is a rand() function in C++ which can be used including cstdlib header file in your program.
You can implement your program using the following code.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int max {100};
int min {0};
int number;
int count = 5; //assuming that only 10 numbers we need to print
srand(time(0));
for(int i=1;i<=count;i++)
{
number = rand() % (max - min +1) + min;``
cout<<number<<endl;
}
}

How can I generate a random number between 5 and 25 in c++ [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Generate Random numbers uniformly over entire range
C++ random float
How can I generate a random number between 5 and 25 in c++ ?
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
void main() {
int number;
int randomNum;
srand(time(NULL));
randomNum = rand();
}
Do rand() % 20 and increment it by 5.
In C++11:
#include <random>
std::default_random_engine re;
re.seed(time(NULL)); // or whatever seed
std::uniform_int_distribution<int> uni(5, 25); // 5-25 *inclusive*
int randomNum = uni(re);
Or it could just as well be:
std::uniform_int_distribution<int> d5(1, 5); // 1-5 inclusive
int randomNum = d5(re) + d5(re) + d5(re) + d5(re) + d5(re);
which would give a different distribution on the same range.
The C++ way:
#include <random>
typedef std::mt19937 rng_type; // pick your favourite (i.e. this one)
std::uniform_int_distribution<rng_type::result_type> udist(5, 25);
rng_type rng;
int main()
{
// seed rng first!
rng_type::result_type random_number = udist(rng);
}
#include <cstdlib>
#include <time.h>
using namespace std;
void main() {
int number;
int randomNum;
srand(time(NULL));
number = rand() % 20;
cout << (number) << endl;
}