2

I have a simple piece of code:

public string GenerateRandomString()
        {
            string randomString = string.Empty;
            Random r = new Random();
            for (int i = 0; i < length; i++)
                randomString += chars[r.Next(chars.Length)];

            return randomString;
        }

If i call this function to generate two strings, one after another, they are identical... but if i debug through the two lines where the strings are generated - the results are different. does anyone know why is it happening?

Rory
  • 40,559
  • 52
  • 175
  • 261
agnieszka
  • 14,897
  • 30
  • 95
  • 113

5 Answers5

6

This is happening, because the calls happen very close to each other (during the same milli-second), then the Random constructor will seed the Random object with the same value (it uses date & time by default).

So, there are two solutions, actually.

1. Provide your own seed value, that would be unique each time you construct the Random object.

2. Always use the same Random object - only construct it once.

Personally, I would use the second approach. It can be done by making the Random object static, or making it a member of the class.

Paulius
  • 5,790
  • 7
  • 42
  • 47
  • yup, Random chooses an initial seed based on current time, so a small time delta will give the same seed. – Jimmy Dec 17 '08 at 22:54
  • Ok, I expanded my answer to be more complete and include not one, but two solutions (I still recommend the one I've given previously). – Paulius Dec 17 '08 at 23:09
  • Just stumbled on this after hours of trying to figure it out, thanks! – Nick Spiers Dec 08 '09 at 18:43
5

The above answers are correct. I would suggest the following changes to your code though:

1) I would suggest using a StringBuilder instead of appending to the string all the time. Strings are immutable, so this is creating a new string each time you add to it. If you have never used StringBuilder, look it up. It is very useful for this sort of work.

2) You can make your method easier to reuse if you pass the length into the method itself. You could probably pass the chars array in as well, but I've left that out.

3) Use the same random object each time, as suggested above.

public string GenerateRandomString(int length)
{
    StringBuilder randomString = new StringBuilder(length);

    for (int i = 0; i < length; i++)
        randomString.Append(chars[(int)(_RandomObj.Next(chars.Length))].ToString());

     return randomString.ToString();
}
Jamie Penney
  • 9,424
  • 3
  • 29
  • 37
2

It's because you're creating two random objects at the same time. This is giving it the same seed, so you're going to get the same numbers.

When you debug it, there's time between the creation of the random objects which allow them to get different seeds.

Rex Morgan
  • 2,979
  • 2
  • 21
  • 32
1

Since the Random generator is tied with the system clock you are probably displaying the same results with that time period. There are several ways to correct. If you are using loops place the Random rnd = new Random(); outside of the loop.

Place the Random rnd = new Random(); line where you declare your variables and use the same variable throughout your program (rnd for this example).

This will work in most cases.

JoeBilly
  • 3,057
  • 29
  • 35
Delmar
  • 11
  • 1
1

The default constructor for Random (the one you're using) seeds the generator with a value based on the current time. If the time in milliseconds doesn't change between the first and second call of the function, it would use the same random seed.

My suggestion is to use a static Random object and only initialize it once.

Ed Marty
  • 39,590
  • 19
  • 103
  • 156