views:

343

answers:

4

I am looking for methods to generate random strings in C++.Here is my code:

string randomStrGen(int length) {
    static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    string result;
    result.resize(length);

    srand(time(NULL));
    for (int i = 0; i < length; i++)
        result[i] = charset[rand() % charset.length()];

    return result;
}

But the seed(time(NULL)) is not random enough.Are there any other better way to generate random strings in C++?

+17  A: 

Don't call srand() on each function call - only call it once at first function call or program startup. You migh want to have a flag indicating whethersrand() has already been called.

The sugested method is good except that you misuse srand() and get predictably bad results.

sharptooth
+1 Excellent answer. One problem with such a flag is that another function that requires random numbers, but using a different flag, will cause problems too. I think it's best if functions needing random numbers just get random numbers, and are decoupled from the generator initialisation. Really, seeding should just be done at the top of `main`. :-)
Chris Jester-Young
Or use the re-entrant versions with their own seed
fa.
@fa: True, that stops generators from stepping on each other, but, if these different functions are all initially run too closely together, you still run into the same problem.
Chris Jester-Young
Re-Using seed values is a bad idea. If you must build your own rand function that calls srand() the first time through (returning the result of rand()).
Martin York
+1  A: 

You can use Boost.Random. It uses a different generator than the one provided with most standard libraries, that should be more robust.

In specific, most standard libraries provide linear congruential generators, which don't perform very well when you mod their results with small numbers. Boost.Random has a Mersenne twister generator.

As sharptooth says, though (good spotting!), only seed the generator once, at the very start of your program. Seeding it every time you want something random is counter-productive.

Chris Jester-Young
Not only seeding on each call is counter-productive but if the function is called repeatedly without a long enough delay it will produce identical results.
sharptooth
Exactly. Really, it'd be best for libraries to do what Perl does in this regard, and do the initialisation itself (with a sensible seed of course) if the program itself hasn't done so. I mean, it's too late for that now, in that standard C libraries can't do it without violating the standard, but you know what I mean. :-)
Chris Jester-Young
+1  A: 

Make an interface to get a random number in this site http://www.random.org/ and you will be sure to get a real random number! But if you are looking for performance...

Phong
A: 

On unix systems you can read random values from the file /dev/random

doron
Unless you're using the numbers for cryptographic purposes, reading straight off `/dev/random` (except to use as a seed to another PRNG) is wasteful.
Chris Jester-Young