Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fast generate a large set of random strings from number and alphabet

I have to generate a large set (10k, and even more) of strings, which is of size 32 chars, randomly from "a-z", "A-Z", and "0-9".

So far, I have the following code (O(N*32)) in my mind, but I wonder if there are better ways to do that.

int N = 10000;           
vector<string> vecStr;

for (int index=0; index<N; index++)
{
  string str;
  for (int i = 0; i < 32; ++i)
  {
    int randomChar = rand()%(26+26+10);        
    if (randomChar < 26)
      str += 'a' + randomChar;
    else if (randomChar < 26+26)
      str += 'A' + randomChar - 26;
    else
      str += '0' + randomChar - 26 - 26;
  }
  vecStr.push_back(str);
} 
like image 918
pepero Avatar asked Oct 22 '13 10:10

pepero


People also ask

How do you generate random alphanumeric strings?

Another way to generate random Strings in Java both alphanumeric and numeric is to use the Math. random() class just like we used it for generating random numbers and pick a random character from a defined character set like a set of uppercase and lowercase alphabets and numbers.

How do you generate unique random strings?

There are many ways to generate a random, unique, alphanumeric string in PHP which are given below: Using str_shuffle() Function: The str_shuffle() function is an inbuilt function in PHP and is used to randomly shuffle all the characters of a string passed to the function as a parameter.

How do you generate a string of random letters in python?

random. choice() is used to generate strings in which characters may repeat, while random. sample() is used for non-repeating characters.


1 Answers

You're not going to find a solution better than O(N*len), where N is the number of strings and len is the length of each therein. That said, somewhere I'm sure there is tarnished sticker I can earn for writing the densest code to do this:

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

int main()
{
    static const char alphabet[] =
        "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "0123456789";

    static const size_t N_STRS = 10000;
    static const size_t S_LEN = 32;

    std::random_device rd;
    std::default_random_engine rng(rd());
    std::uniform_int_distribution<> dist(0,sizeof(alphabet)/sizeof(*alphabet)-2);

    std::vector<std::string> strs;
    strs.reserve(N_STRS);
    std::generate_n(std::back_inserter(strs), strs.capacity(),
        [&] { std::string str; 
              str.reserve(S_LEN); 
              std::generate_n(std::back_inserter(str), S_LEN,
                   [&]() { return alphabet[dist(rng)];}); 
              return str; });
    std::copy(strs.begin(), strs.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    return 0;
}

Output (9990 lines omitted for brevity =P)

MRdeOWckfKy8GTFt0YmQMcM6SABJc934
XvdcatVsv6N9c1PzQGFFY6ZP943yIrUY
xpHzxUUyAizB6BfKldQzoePrm82PF1bn
kMUyPbflxk3yj3IToTFqYWnDq6aznKas
Ey0W5SF37VaeEY6PxWsBoxlNZTv9lOUn
iTx7jFRTHHW6TfYl7N3Hne4yu7kgAzp5
0ZamlaopjLyEvJbr6fzJPdXmjLOohtKh
6ZYeqj47nCMYKj0sCGl2IHm28FmvuH8h
oTDYRIA1trN1A2pQjsBwG3j9llzKIMhw
5zlpvSgTeLQ38eFWeSDoSY9IHEMHyzix

And note you may be surprised how fast this runs. There is quite a lot going on under the hood. Finally, this uses the C++11 random library, in particular the uniform distribution, which eliminates modulus-bias typically encountered with traditional rand() % n solutions for particular n.

like image 168
WhozCraig Avatar answered Sep 21 '22 02:09

WhozCraig