可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to create a block of unique lines to test a different project I am working on.
So I created a simple program to generate a random string of X length.
The issue is that if I call it once, I get a random string, if I call it again (in a for loop for example) I get the same string for the entire execution of the loop.
I have a feeling that it's being cached or something but I didn't know .net did that and I am just confused at this point.
calling code:
StreamWriter SW = new StreamWriter("c:\\test.txt");
int x = 100;
while (x >0)
{
SW.WriteLine(RandomString(20));
x--;
}
here is the method:
private static string RandomString(int Length)
{
StringBuilder sb = new StringBuilder();
Random randomNumber = new Random();
for (int i = 0; i <= Length; ++i)
{
int x = randomNumber.Next(65, 122);
sb.Append(Convert.ToChar(x));
}
return sb.ToString();
}
and here is the output:
"VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
..................
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB"
So what gives i thought Random.next() would always return a new random number?
回答1:
You are creating the Random
instances too close in time. Each instance is initialised using the system clock, and as the clock haven't changed you get the same sequence of random numbers over and over.
Create a single instance of the Random
class and use it over and over.
Use the using
keyword so that the StreamWriter
is closed and disposed when you are done with it. The code for a loop is easier to recognise if you use the for
keyword.
using (StreamWriter SW = new StreamWriter("c:\\test.txt")) {
Random rnd = new Random();
for (int x = 100; x > 0; x--) {
SW.WriteLine(RandomString(rnd, 20));
}
}
The method takes the Random
object as a parameter.
Also, use the length to initialise the StringBuilder with the correct capacity, so that it doesn't have to reallocate during the loop. Use the < operator instead of <= in the loop, otherwise you will create a string that is one character longer than the length
parameter specifies.
private static string RandomString(Random rnd, int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int x = rnd.Next(65, 122);
sb.Append((char)x);
}
return sb.ToString();
}
回答2:
See Random constructor description at MSN, this part:
The default seed value is derived from
the system clock and has finite
resolution. As a result, different
Random objects that are created in
close succession by a call to the
default constructor will have
identical default seed values and,
therefore, will produce identical sets
of random numbers.
So either call the Random() constructor only once at the beginning of your program or use the Random(int32) constructor and define a varying seed yourself.
回答3:
Because you create a new Random object in each call.
Simply move the randomNumber out of the method and make it a class member.
private Random randomNumber = new Random();
private static string RandomString(int Length)
{
StringBuilder sb = new StringBuilder();
//...
}
All software Random generators are 'pseudo random' , they produce a sequence of numbers bases on a (starting) seed. With the same seed they produce the same sequence. Sometimes this is usefull. If you want to produce your program to produce the same sequence on each run, you can use new Random(0)
.
Edit: apparently the .Net Random class is auto-seeding, I didn't know that. So it is a timing problem, as others have pointed out.
回答4:
only declare randomNumber once
public class MyClass
{
private static Random randomNumber = new Random();
private static string RandomString(int Length)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i ... Length; ++i)
{
int x = MyClass.randomNumber.Next(65, 122);
sb.Append(Convert.ToChar(x));
}
return sb.ToString();
}
}
回答5:
Similar question, lots of answers:
random string generation - two generated one after another give same results
回答6:
the seed for the random numbers are all the same due to the short amount of time it takes, in effect you recreate the random generator with the same seed every time, so the Next() call returns the same random value.