How do I create a random alpha-numeric string in C++?

C++StringRandom

C++ Problem Overview


I'd like to create a random string, consisting of alpha-numeric characters. I want to be able to be specify the length of the string.

How do I do this in C++?

C++ Solutions


Solution 1 - C++

Mehrdad Afshari's answer would do the trick, but I found it a bit too verbose for this simple task. Look-up tables can sometimes do wonders:

#include <ctime>
#include <iostream>
#include <unistd.h>

std::string gen_random(const int len) {
	static const char alphanum[] =
		"0123456789"
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz";
	std::string tmp_s;
	tmp_s.reserve(len);

	for (int i = 0; i < len; ++i) {
		tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)];
	}
	
	return tmp_s;
}

int main(int argc, char *argv[]) {
	srand((unsigned)time(NULL) * getpid());    	
	std::cout << gen_random(12) << "\n";    	
	return 0;
}

Note that rand generates poor-quality random numbers.

Solution 2 - C++

Here's my adaptation of Ates Goral's answer using C++11. I've added the lambda in here, but the principle is that you could pass it in and thereby control what characters your string contains:

std::string random_string( size_t length )
{
    auto randchar = []() -> char
    {
        const char charset[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(length,0);
    std::generate_n( str.begin(), length, randchar );
    return str;
}

Here is an example of passing in a lambda to the random string function: http://ideone.com/Ya8EKf

Why would you use C++11?

  1. Because you can produce strings that follow a certain probability distribution (or distribution combination) for the character set you're interested in.
  2. Because it has built-in support for non-deterministic random numbers
  3. Because it supports unicode, so you could change this to an internationalized version.

For example:

#include <iostream>
#include <vector>
#include <random>
#include <functional> //for std::function
#include <algorithm>  //for std::generate_n

typedef std::vector<char> char_array;

char_array charset()
{
    //Change this to suit
    return char_array( 
	{'0','1','2','3','4',
	'5','6','7','8','9',
	'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',
	'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'
	});
};    

// given a function that generates a random character,
// return a string of the requested length
std::string random_string( size_t length, std::function<char(void)> rand_char )
{
    std::string str(length,0);
    std::generate_n( str.begin(), length, rand_char );
    return str;
}

int main()
{
    //0) create the character set.
    //   yes, you can use an array here, 
    //   but a function is cleaner and more flexible
    const auto ch_set = charset();

    //1) create a non-deterministic random number generator      
    std::default_random_engine rng(std::random_device{}());

    //2) create a random number "shaper" that will give
    //   us uniformly distributed indices into the character set
    std::uniform_int_distribution<> dist(0, ch_set.size()-1);

    //3) create a function that ties them together, to get:
    //   a non-deterministic uniform distribution from the 
    //   character set of your choice.
    auto randchar = [ ch_set,&dist,&rng ](){return ch_set[ dist(rng) ];};

    //4) set the length of the string you want and profit!        
    auto length = 5;
    std::cout<<random_string(length,randchar)<<std::endl;
    return 0;
}

Sample output.

Solution 3 - C++

My 2p solution:

#include <random>
#include <string>

std::string random_string(std::string::size_type length)
{
    static auto& chrs = "0123456789"
        "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    thread_local static std::mt19937 rg{std::random_device{}()};
    thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);

    std::string s;

    s.reserve(length);

    while(length--)
        s += chrs[pick(rg)];

    return s;
}

Solution 4 - C++

Rather than manually looping, prefer using the appropriate C++ algorithm, in this case std::generate_n, with a proper random number generator:

auto generate_random_alphanumeric_string(std::size_t len) -> std::string {
    static constexpr auto chars =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    thread_local auto rng = random_generator<>();
    auto dist = std::uniform_int_distribution{{}, std::strlen(chars) - 1};
    auto result = std::string(len, '\0');
    std::generate_n(begin(result), len, [&]() { return chars[dist(rng)]; });
    return result;
}

This is close to something I would call the “canonical” solution for this problem.

Unfortunately, correctly seeding a generic C++ random number generator (e.g. MT19937) is really hard. The above code therefore uses a helper function template, random_generator:

template <typename T = std::mt19937>
auto random_generator() -> T {
    auto constexpr seed_bytes = sizeof(typename T::result_type) * T::state_size;
    auto constexpr seed_len = seed_bytes / sizeof(std::seed_seq::result_type);
    auto seed = std::array<std::seed_seq::result_type, seed_len>();
    auto dev = std::random_device();
    std::generate_n(begin(seed), seed_len, std::ref(dev));
    auto seed_seq = std::seed_seq(begin(seed), end(seed));
    return T{seed_seq};
}

This is complex and relatively inefficient. Luckily it’s used to initialise a thread_local variable and is therefore only invoked once per thread.

Finally, the necessary includes for the above are:

#include <algorithm>
#include <array>
#include <cstring>
#include <functional>
#include <random>
#include <string>

The above code uses class template argument deduction and thus requires C++17. It can be trivially adapted for earlier versions by adding the required template arguments.

Solution 5 - C++

 void gen_random(char *s, size_t len) {
     for (size_t i = 0; i < len; ++i) {
         int randomChar = rand()%(26+26+10);
         if (randomChar < 26)
             s[i] = 'a' + randomChar;
         else if (randomChar < 26+26)
             s[i] = 'A' + randomChar - 26;
         else
             s[i] = '0' + randomChar - 26 - 26;
     }
     s[len] = 0;
 }
            

Solution 6 - C++

I just tested this, it works sweet and doesn't require a lookup table. rand_alnum() sort of forces out alphanumerics but because it selects 62 out of a possible 256 chars it isn't a big deal.

#include <cstdlib>   // for rand()
#include <cctype>    // for isalnum()   
#include <algorithm> // for back_inserter
#include <string>

char 
rand_alnum()
{
    char c;
    while (!std::isalnum(c = static_cast<char>(std::rand())))
        ;
    return c;
}


std::string 
rand_alnum_str (std::string::size_type sz)
{
    std::string s;
    s.reserve  (sz);
    generate_n (std::back_inserter(s), sz, rand_alnum);
    return s;
}

Solution 7 - C++

I hope this helps someone.

Tested at https://www.codechef.com/ide with C++ 4.9.2

#include <iostream>
#include <string>
#include <stdlib.h>     /* srand, rand */

using namespace std;

string RandomString(int len)
{
   string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   string newstr;
   int pos;
   while(newstr.size() != len) {
    pos = ((rand() % (str.size() - 1)));
    newstr += str.substr(pos,1);
   }
   return newstr;
}

int main()
{
   srand(time(0));
   string random_str = RandomString(100);
   cout << "random_str : " << random_str << endl;
}

Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd

Solution 8 - C++

Here's a funny one-liner. Needs ASCII.

void gen_random(char *s, int l) {
    for (int c; c=rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0););
}

Solution 9 - C++

#include <iostream>
#include <string>
#include <random>

std::string generateRandomId(size_t length = 0)
{
    static const std::string allowed_chars {"123456789BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"};

    static thread_local std::default_random_engine randomEngine(std::random_device{}());
    static thread_local std::uniform_int_distribution<int> randomDistribution(0, allowed_chars.size() - 1);

    std::string id(length ? length : 32, '\0');

    for (std::string::value_type& c : id) {
        c = allowed_chars[randomDistribution(randomEngine)];
    }

    return id;
}

int main()
{
    std::cout << generateRandomId() << std::endl;
}

Solution 10 - C++

The most suitable function in standard library is std::sample:

#include <algorithm>
#include <iterator>
#include <random>
#include <string>
#include <iostream>

static const char charset[] = 
    "0123456789"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz";

template<typename URBG>
std::string gen_string(std::size_t length, URBG&& g) {
    std::string result;
    result.resize(length);
    std::sample(std::cbegin(charset), 
                std::cend(charset),
                std::begin(result),
                std::intptr_t(length),
                std::forward<URBG>(g));
    return result;
}

int main() {
    std::mt19937 g;
    std::cout << gen_string(10, g) << std::endl;
    std::cout << gen_string(10, g) << std::endl;
}

State of random number generator should be kept outside of the function between calls.

Solution 11 - C++

Let's make random convenient again!

I made up a nice C++11 header only solution. You could easily add one header file to your project and then add your tests or use random strings for another purposes.

That's a quick description, but you can follow the link to check full code. The main part of solution is in class Randomer:

class Randomer {
    // random seed by default
    std::mt19937 gen_;
    std::uniform_int_distribution<size_t> dist_;
    
public:
    /* ... some convenience ctors ... */
    
    Randomer(size_t min, size_t max, unsigned int seed = std::random_device{}())
        : gen_{seed}, dist_{min, max} {
    }

    // if you want predictable numbers
    void SetSeed(unsigned int seed) {
        gen_.seed(seed);
    }

    size_t operator()() {
        return dist_(gen_);
    }
};

Randomer incapsulates all random stuff and you can add your own functionality to it easily. After we have Randomer, it's very easy to generate strings:

std::string GenerateString(size_t len) {
    std::string str;
    auto rand_char = [](){ return alphabet[randomer()]; };
    std::generate_n(std::back_inserter(str), len, rand_char);
    return str;
}

Write your suggestions for improvement below. https://gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad

Solution 12 - C++

Something even simpler and more basic in case you're happy for your string to contain any printable characters:

#include <time.h>   // we'll use time for the seed
#include <string.h> // this is for strcpy

void randomString(int size, char* output) // pass the destination size and the destination itself
{
    srand(time(NULL)); // seed with time

    char src[size];
    size = rand() % size; // this randomises the size (optional)

    src[size] = '\0'; // start with the end of the string...
    
    // ...and work your way backwards
    while(--size > -1)
        src[size] = (rand() % 94) + 32; // generate a string ranging from the space character to ~ (tilde)

    strcpy(output, src); // store the random string
}

Solution 13 - C++

Example for Qt use:)

QString random_string(int length=32, QString allow_symbols=QString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")) {
    QString result;
    qsrand(QTime::currentTime().msec());
    for (int i = 0; i < length; ++i) {            
        result.append(allow_symbols.at(qrand() % (allow_symbols.length())));
    }
    return result;
}

Solution 14 - C++

Yet another adaptation because none of the answers would suffice for my needs.

First of all, if rand() is used to generate random numbers you will get the same output at each run. The seed for random number generator has to be some sort of random.

With C++11 you can include the random library and you can initialize the seed with random_device and mt19937. This seed will be supplied by the OS and it will be random enough for us (for example, clock). You can give a range boundaries to be included ([0,25] in my case`.

I only needed random string of lowercase letters so I utilized char addition. The pool of characters approach did not work out for me.

#include <random>    
void gen_random(char *s, const int len){
    static std::random_device rd;
    static std::mt19937 mt(rd());
    static std::uniform_int_distribution<int> dist(0, 25);
    for (int i = 0; i < len; ++i) {
        s[i] = 'a' + dist(mt);
    }
    s[len] = 0;
}

Solution 15 - C++

You can use the random() method to generate a basic random string. The code below generates a random string composed of lowercase letters, uppercase letters and digits.

String randomStrGen(int numChars){
  String genStr="";
  int sizeStr=0;
  
  while(sizeStr<numChars){
    int asciiPos= random(48,122);
    if((asciiPos>57 && asciiPos<65) || (asciiPos>90 && asciiPos<97))
      continue;
    genStr+=(char) asciiPos;
    sizeStr++;
  }
  
  return genStr;
}

if one needs a more secure random number generator, simply replace the random() function for a more secure one.

Also, one can also tweak the possible characters generated by changing the ASCII limits (48,122) to another custom values

Solution 16 - C++

Random string, every run file = different string

		auto randchar = []() -> char
	{
		const char charset[] =
			"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
			"abcdefghijklmnopqrstuvwxyz";

		const size_t max_index = (sizeof(charset) - 1);

		return charset[randomGenerator(0, max_index)];
	};
            std::string custom_string;
            size_t LENGTH_NAME = 6 // length of name
	generate_n(custom_string.begin(), LENGTH_NAME, randchar);

Solution 17 - C++

Be ware when calling the function

string gen_random(const int len) {
static const char alphanum[] = "0123456789"
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

stringstream ss;

for (int i = 0; i < len; ++i) {
	ss << alphanum[rand() % (sizeof(alphanum) - 1)];
}
return ss.str();
}

(adapted of @Ates Goral) it will result in the same character sequence every time. Use

srand(time(NULL));

before calling the function, although the rand() function is always seeded with 1 @kjfletch.

For Example:

void SerialNumberGenerator() {

	srand(time(NULL));
	for (int i = 0; i < 5; i++) {
		cout << gen_random(10) << endl;
	}
}

Solution 18 - C++

#include <iostream>
#include <string>
#include <stdlib.h>
int main()
{
	int size;
	std::cout << "Enter size : ";
	std::cin >> size;
	std::string str;
	for (int i = 0; i < size; i++)
	{
		auto d = rand() % 26 + 'a';
		str.push_back(d);
	}
	for (int i = 0; i < size; i++)
	{
		std::cout << str[i] << '\t';
	}
	
	return 0;
}

Solution 19 - C++

//C++ Simple Code
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<char> alphanum =
    {'0','1','2','3','4',
'5','6','7','8','9',
'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',
'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'
};
string s="";
int len=5;
srand(time(0)); 
for (int i = 0; i <len; i++) {
    int t=alphanum.size()-1;
    int idx=rand()%t;
    s+= alphanum[idx];
}
cout<<s<<" ";
return 0;
}

Solution 20 - C++

void strGetRandomAlphaNum(char *sStr, unsigned int iLen)
{
  char Syms[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  unsigned int Ind = 0;
  srand(time(NULL) + rand());
  while(Ind < iLen)
  {
    sStr[Ind++] = Syms[rand()%62];
  }
  sStr[iLen] = '\0';
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionjm.View Question on Stackoverflow
Solution 1 - C++Ates GoralView Answer on Stackoverflow
Solution 2 - C++CarlView Answer on Stackoverflow
Solution 3 - C++GalikView Answer on Stackoverflow
Solution 4 - C++Konrad RudolphView Answer on Stackoverflow
Solution 5 - C++mmxView Answer on Stackoverflow
Solution 6 - C++nlyView Answer on Stackoverflow
Solution 7 - C++D DView Answer on Stackoverflow
Solution 8 - C++gezaView Answer on Stackoverflow
Solution 9 - C++OlegView Answer on Stackoverflow
Solution 10 - C++Tomilov AnatoliyView Answer on Stackoverflow
Solution 11 - C++Gusev SlavaView Answer on Stackoverflow
Solution 12 - C++NobilisView Answer on Stackoverflow
Solution 13 - C++Vitalja AlexView Answer on Stackoverflow
Solution 14 - C++Barkin KaplanView Answer on Stackoverflow
Solution 15 - C++Miguel SilvaView Answer on Stackoverflow
Solution 16 - C++NehigienixView Answer on Stackoverflow
Solution 17 - C++Mr.SheepView Answer on Stackoverflow
Solution 18 - C++rasView Answer on Stackoverflow
Solution 19 - C++JK25View Answer on Stackoverflow
Solution 20 - C++Деян ДобромировView Answer on Stackoverflow