I need to create random numbers between 0 and upto 2 so I am using:
//field level
private static Random _random = new Random();
//used in a method
_random.Next(0, 2)
My question is: will the sequence ever repeat / stop been random? Should I recreate (_random = new Random();) every day?
Your code is fine as it is.
You do not need to create a new Random object daily.
Note that Random is not truly random, but produces a pseudo-random result.
If you check the 'remarks' section in the documentation you will find that System.Random is a pseudo-random generator.
This means in theory the sequence does eventually repeat. In practice it very much depends on what you're doing as to how much this matters. For example, the length of the sequence is such that no human will ever notice them repeating. On the otherhand, it's pretty useless for cryptography.
Edit to add: restarting daily won't make much difference. Either the pseudo-randomness is sufficient for you or you need to look into cryptographically secure way of generating random numbers.
Math.Random returns a 32-bit signed integer, it will repeat on the 2^32'nd call if you dont reseed. If you DO reseed it will repeat itself sooner.
Random is not that random. If you need "more" random, you should have a look a cryptographic classes, such as RandomNumberGenerator (abstract), for example: RNGCryptoServiceProvider
If you read this, you'll see that Random is (currently) based on the subtractive lagged Fibonacci generator of (24, 55) which should guarantee the period to be at least 2^55 . BUT if you look at the end of the page, someone has pointed to a possible bug (the comment of ytosa on October 2010)
http://msdn.microsoft.com/en-us/library/system.random(v=vs.100).aspx
Lets say that the period is long enough unless you need to do "special" applications!
I will add that the Wiki http://en.wikipedia.org/wiki/Lagged_Fibonacci_generator tells us there is a paper that shows that the 24, 55 sequence of lagged Fibonacci isn't "random enough" (under Problems with LFG)
If the purpose is to generate cryptographically secure random numbers, you should probably use a better PRNG. If you just want the occasional random number and true randomness isn't critical (which I imagine given the output values range) then your code is most likely just fine as it is.
It worth mention (at list by my experience) that if you have a method when you declare :
Random myRand=new Random();
myRand.Next(10);
//...doing somthing with that
and then, if you call this method many times (in a loop) , you might ends up with a lot of duplicates results. (that what happend to me).
and the solution I found was to move Random myRand=new Random() to be a class member initiation statment ( instead of a local variable of a method), match like you did.
after that , there were no longer duplicated results
Related
I tried to understand better random number generating process, in particular pseudorandom number generation in .NET (actually MONO), and I am after reading these articles: MSDN Random, wikipedia Random number generation.
So I think I get it (.NET uses modified version of Donald E. Knuth's subtractive random number generator algorithm).
The only thing that stays unclear to me is how this algorithm gets its first seed number. I tried to find info, but didn't.
Does it takes from pseudorandom number generator too? It doesnt make sense, does it? First seed needs to be somehow random too, couse if not first random number in every instance of .NET application would be the same. If so, quessing next results from applications like games would be quite easy (if the author of application didn't modify the number after generation). So I am quessing the first seed number, I mean first input to the generator must be taken from something unique for machine or current application process, but I am just quessing.
So my question is: If my thinking process is correct (if not please correct me), how generator gets its first input for given algorithm?
From the Reference Random Class
public Random()
: this(Environment.TickCount) {
}
public Random(int Seed) {
///....
}
It's calculated based on your input or the Tick count
The default seed value is derived from the system clock
source Random() constructor
So separate instances get different random values. However if you create multiple instances of this class quickly, they may end up using the same clock-tick as seed - and thus generate the same sequence.
The Random class has a constructor that takes either no or one parameter of type int. Thus you can set the initial seed by your own.
If you do not provide a parameter than as the documentations says a time-dependent value is used as seed. The default values is the number of ticks (see source) that have elapsed since the system started up.
System.Random uses Environment.TickCount as the seed in its parameterless constructor, as per .NET source.
I have to port a c++ program to C#.
Random numbers are involved in the program. I have to produce exactly same random numbers in both program to get same results in testing.
In C++ I use
srand(1000)
...
double r = (double)rand() / (double)(RAND_MAX);
and in C# I use
private readonly Random _rnd = new Random(1000);
...
_rnd.NextDouble()
However programs produces different numbers despite same seed. Is there any way to produce same random numbers?
Do you know, what algorithm is used for c++ rand and c# Random class?
You can try to implement some PNG on your own. Eg. LCG algorithm is very simple and easily implementable in both languages...Just use some common parameters from the wiki page.
Essentially both random functions (srand vs Random) have different underlying implementations, thus you can't rely on them giving the same output. So why not provide a set of "n" numbers and feed them into your algorithm in both c++ and c# - just for testing purposes ofcourse? This way you're always certain you'll have the same amount, the same numbers and the same order.
e.g.: a file with on every line some numbers, then read it out in both c++/c# and then feed those numbers into the algorithm you're trying to "test".
(Also, what is it that you want to test here? An algorithm you wrote (the ported algorithm thus), or the "random" capabilities in both languages?
Because, depending on your answer to my questions above, the answer that would be relevant to your case might differ a lot! So could you provide us with some more context?)
i used this
Random rnd = new Random();
as my declaration.
and this:
Convert.ToString(rnd.Next(1, 49))
as the execution when the button is pressed.
maybe you can have a useful use of this.
Greetings
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does it appear that my random number generator isn't random in C#?
How can I generate truly (not pseudo) random numbers with C#?
I've created a dice game where the dice is based on a percentile, 1-100.
public static void Roll()
{
Random rand = new Random((int)DateTime.Now.Ticks);
return rand.Next(1, 100);
}
But I don't feel like it's a real random based on current time.
If I do
for (int i = 0; i < 5; i++)
{
Console.WriteLine("#" + i + " " + Roll());
}
They would all be the same values, because the DateTime.Now.Ticks didn't change, it seeded the same number.
I was thinking I could generate a new random seed if the seed was the same due to the current time, but it doesn't feel like an honest "re-roll"
What should I do to try and replicate a close to real/honest dice roll? Should I use the RNGCryptoServiceProvider class to generate rolls instead?
DateTime.Now.Ticks only has a resolution of approximately 16ms, so if you create a Random with that overload multiple times within a 16ms "slot" they will all be seeded with the same value and therefore you will get the same sequence.
Initialize your Random outside your loop so that a single Random sequence is produced, rather than creating it each time within the loop which could result in Randoms being seeded with the same value and so produce the same sequence.
Update
My previous point that the default constructor initialized Random with CPU ticks was incorrect, the default constructor actually uses Environment.TickCount which is:
A 32-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started.
Which still has a low resolution. If you make multiple instances of Random in quick succession, they can easily be created within the same time slot and therefore have the same seed value, and create the same sequence. Create a single instance of Random and use that.
Update
Further to your comments, if you wish to generate a random sequence across multiple threads, please see the following Jon Skeet article which discusses a thread-safe wrapper:
https://codeblog.jonskeet.uk/2009/11/04/revisiting-randomness
Pseudo-random number generators like Random should only be seeded once, so:
private static Random _rand = new Random();
public static int Roll()
{
return _rand.Next(1, 100);
}
(Note I made the return value int rather than void; the Roll function as quoted in the question results in a syntax error.)
But your title says "Creating a true random". Random won't do that for you, it's a pseudo-random number generator, meaning it's deterministic, just hard to predict if you don't know the seed. Usually that's good enough for most purposes, but if you need real randomness, you need an entropy source. http://random.org is one popular one.
You should create your Random class only once outside your Roll function and seed it with a unique value.
You are recreating your Random each time you call Roll which causes the 'not random numbers'.
Should I use the RNGCryptoServiceProvider class to generate rolls instead?
If this is a serious game with money at stake then: Yes.
I'm assuming that you are calling the Roll() method so quickly that Now.Ticks is the same?
The simplest way to get around this would be rather than to create a new Random() instance each time you call Roll() create a static variable to hold a single instance of Random().
The usual way to use random number generators is to seed them once, save them and call on them repeatedly throughout your programme. As long as you seed from a suitable value at the start, you should get acceptable randomness - assuming the generator you're using is using a function returning things which are suitably random for your purposes. So, save your Random instance outside the Roll() function, seed it the first time it's used, then just call Next() on it each time you need another number.
When you get right down to it, there's no such thing as true random number generation on a computer, only pseudorandom sequences based on a seed. However, humans are terrible at identifying randomness, so it's usually okay.
I know C# has the Random class and probably a few classes in LINQ to do this, but if I was to write my own code to randomly select an item from a collection without using any built in .NET objects, how would this be done?
I can't seem to nail the logic required for this - how would I tell the system when to stop an iteration and select the current value - at random?
EDIT: This is a hypothetical question. This is not related to a production coding matter. I am just curious.
Selecting a random element from a collection can be done as follows.
Random r = new Random();
int randomIndex = r.Next(0, myCollection.Size -1);
var randomCollectionItem = myCollection[randomIndex];
Unless you have a VERY good reason, writing your own random generator is not necessary.
My advice to you is DON'T DO IT. Whatever reason you think you may have for not wanting to use the built-in library, I am pretty sure you misunderstood something. Please go back to the drawing board.
All of the advice above is technically accurate, but is kind of like giving a chemistry textbook to someone who wants to refine his own oil to use in his car.
There are many pseudo-random number generators. They aren't truly random, but they come at different quality, distinguished by their statistical and sequential properties and what purpose they are applicable for.
It very much depends on "how random you need it". If it just needs to "look random to a human", simple generators look like that:
rnd = seed; // some starting value
rnd = (a * rnd + b) % c; // next value
...
For well chosen values of a, b, and cthese generators are ok for simple statistical tests. A detailed discussion and common values for these you find here.
One interesting approach is to collect as much "external" data as possible - like time between keypresses, mouse movements, duration of disk reads etc. -, and use an algorithm that accumulates randomness while discarding dependency. That is mathematically tricky though (IIRC not long ago a critical attack surfaced based on one of these not being as random as thought).
Only a very few special applications use a truly random external hardware source - anything between a open-imput amplifier and radioactive decay.
You need to use a seed, something semi random provided by the computer itself.
Maybe use very fine resolution time and use the last couple microseconds when the method is called. That should be random enough to generate anything from 00 to 99, you can then go from there.
It sounds like your problem isn't in calculating a random number, but in how to use that random number to select an item from a list. Assuming you can create a random number somehow, all you need to do is use it as the argument to the list's indexer.
int index = customRandomGenerator.Next();
var selection = items[index];
Assuming that your presupposition about having to iterate through the list is correct (or the collection doesn't have an indexer) then you could do:
int index = customRandomGenerator.Next();
Item selection = null;
for (int i = 0; i < items.Length; i++)
{
if (i == index)
{
selection = items[i];
break;
}
}
The only true "cryptographically strong" random number generator in the .Net Framework is in System.Cryptography.RandomNumberGenerator - run this through Reflector to see what is does? Looking at your problem you would need a to know the Count of the collection otherwise you may never retrieve an item - you would need to specify a start and end value to draw random numbers from - the Random class would work best - pop it through Reflector.
Well, I never thought about implementing that myself as it seems like reinventing the wheel but you may have a look on this wikipedia article, hope it helps you do what you want
Random Number Generator
Why would anybody use the "standard" random number generator from System.Random at all instead of always using the cryptographically secure random number generator from System.Security.Cryptography.RandomNumberGenerator (or its subclasses because RandomNumberGenerator is abstract)?
Nate Lawson tells us in his Google Tech Talk presentation "Crypto Strikes Back" at minute 13:11 not to use the "standard" random number generators from Python, Java and C# and to instead use the cryptographically secure version.
I know the difference between the two versions of random number generators (see question 101337).
But what rationale is there to not always use the secure random number generator? Why use System.Random at all? Performance perhaps?
Speed and intent. If you're generating a random number and have no need for security, why use a slow crypto function? You don't need security, so why make someone else think that the number may be used for something secure when it won't be?
Apart from the speed and the more useful interface (NextDouble() etc) it is also possible to make a repeatable random sequence by using a fixed seed value. That is quite useful, amongst others during Testing.
Random gen1 = new Random(); // auto seeded by the clock
Random gen2 = new Random(0); // Next(10) always yields 7,8,7,5,2,....
First of all the presentation you linked only talks about random numbers for security purposes. So it doesn't claim Random is bad for non security purposes.
But I do claim it is. The .net 4 implementation of Random is flawed in several ways. I recommend only using it if you don't care about the quality of your random numbers. I recommend using better third party implementations.
Flaw 1: The seeding
The default constructor seeds with the current time. Thus all instances of Random created with the default constructor within a short time-frame (ca. 10ms) return the same sequence. This is documented and "by-design". This is particularly annoying if you want to multi-thread your code, since you can't simply create an instance of Random at the beginning of each thread's execution.
The workaround is to be extra careful when using the default constructor and manually seed when necessary.
Another problem here is that the seed space is rather small (31 bits). So if you generate 50k instances of Random with perfectly random seeds you will probably get one sequence of random numbers twice (due to the birthday paradox). So manual seeding isn't easy to get right either.
Flaw 2: The distribution of random numbers returned by Next(int maxValue) is biased
There are parameters for which Next(int maxValue) is clearly not uniform. For example if you calculate r.Next(1431655765) % 2 you will get 0 in about 2/3 of the samples. (Sample code at the end of the answer.)
Flaw 3: The NextBytes() method is inefficient.
The per byte cost of NextBytes() is about as big as the cost to generate a full integer sample with Next(). From this I suspect that they indeed create one sample per byte.
A better implementation using 3 bytes out of each sample would speed NextBytes() up by almost a factor 3.
Thanks to this flaw Random.NextBytes() is only about 25% faster than System.Security.Cryptography.RNGCryptoServiceProvider.GetBytes on my machine (Win7, Core i3 2600MHz).
I'm sure if somebody inspected the source/decompiled byte code they'd find even more flaws than I found with my black box analysis.
Code samples
r.Next(0x55555555) % 2 is strongly biased:
Random r = new Random();
const int mod = 2;
int[] hist = new int[mod];
for(int i = 0; i < 10000000; i++)
{
int num = r.Next(0x55555555);
int num2 = num % 2;
hist[num2]++;
}
for(int i=0;i<mod;i++)
Console.WriteLine(hist[i]);
Performance:
byte[] bytes=new byte[8*1024];
var cr=new System.Security.Cryptography.RNGCryptoServiceProvider();
Random r=new Random();
// Random.NextBytes
for(int i=0;i<100000;i++)
{
r.NextBytes(bytes);
}
//One sample per byte
for(int i=0;i<100000;i++)
{
for(int j=0;j<bytes.Length;j++)
bytes[j]=(byte)r.Next();
}
//One sample per 3 bytes
for(int i=0;i<100000;i++)
{
for(int j=0;j+2<bytes.Length;j+=3)
{
int num=r.Next();
bytes[j+2]=(byte)(num>>16);
bytes[j+1]=(byte)(num>>8);
bytes[j]=(byte)num;
}
//Yes I know I'm not handling the last few bytes, but that won't have a noticeable impact on performance
}
//Crypto
for(int i=0;i<100000;i++)
{
cr.GetBytes(bytes);
}
System.Random is much more performant since it does not generate cryptographically secure random numbers.
A simple test on my machine filling a buffer of 4 bytes with random data 1,000,000 times takes 49 ms for Random, but 2845 ms for RNGCryptoServiceProvider. Note that if you increase the size of the buffer you are filling, the difference narrows as the overhead for RNGCryptoServiceProvider is less relevant.
The most obvious reasons have already been mentioned, so here's a more obscure one: cryptographic PRNGs typically need to be continually be reseeded with "real" entropy. Thus, if you use a CPRNG too often, you could deplete the system's entropy pool, which (depending on the implementation of the CPRNG) will either weaken it (thus allowing an attacker to predict it) or it will block while trying to fill up its entropy pool (thus becoming an attack vector for a DoS attack).
Either way, your application has now become an attack vector for other, totally unrelated applications which – unlike yours – actually vitally depend on the cryptographic properties of the CPRNG.
This is an actual real world problem, BTW, that has been observed on headless servers (which naturally have rather small entropy pools because they lack entropy sources such as mouse and keyboard input) running Linux, where applications incorrectly use the /dev/random kernel CPRNG for all sorts of random numbers, whereas the correct behavior would be to read a small seed value from /dev/urandom and use that to seed their own PRNG.
If you're programming an online card game or lotter then you would want to make sure the sequence is next to impossible to guess. However, if you are showing users, say, a quote of the day the performance is more important than security.
This has been discussed at some length, but ultimately, the issue of performance is a secondary consideration when selecting a RNG. There are a vast array of RNGs out there, and the canned Lehmer LCG that most system RNGs consists of is not the best nor even necessarily the fastest. On old, slow systems it was an excellent compromise. That compromise is seldom ever really relevant these days. The thing persists into present day systems primarily because A) the thing is already built, and there is no real reason to 'reinvent the wheel' in this case, and B) for what the vast bulk of people will be using it for, it's 'good enough'.
Ultimately, the selection of an RNG comes down to Risk/Reward ratio. In some applications, for example a video game, there is no risk whatsoever. A Lehmer RNG is more than adequate, and is small, concise, fast, well-understood, and 'in the box'.
If the application is, for example, an on-line poker game or lottery where there are actual prizes involved and real money comes into play at some point in the equation, the 'in the box' Lehmer is no longer adequate. In a 32-bit version, it only has 2^32 possible valid states before it begins to cycle at best. These days, that's an open door to a brute force attack. In a case like this, the developer will want to go to something like a Very Long Period RNG of some species, and probably seed it from a cryptographically strong provider. This gives a good compromise between speed and security. In such a case, the person will be out looking for something like the Mersenne Twister, or a Multiple Recursive Generator of some kind.
If the application is something like communicating large quantities of financial information over a network, now there is a huge risk, and it heavily outweights any possible reward. There are still armored cars because sometimes heavily armed men is the only security that's adequate, and trust me, if a brigade of special ops people with tanks, fighters, and helicopters was financially feasible, it would be the method of choice. In a case like this, using a cryptographically strong RNG makes sense, because whatever level of security you can get, it's not as much as you want. So you'll take as much as you can find, and the cost is a very, very remote second-place issue, either in time or money. And if that means that every random sequence takes 3 seconds to generate on a very powerful computer, you're going to wait the 3 seconds, because in the scheme of things, that is a trivial cost.
Note that the System.Random class in C# is coded incorrectly, so should be avoided.
https://connect.microsoft.com/VisualStudio/feedback/details/634761/system-random-serious-bug#tabs
Not everyone needs cryptographically secure random numbers, and they might benefit more from a speedier plain prng. Perhaps more importantly is that you can control the sequence for System.Random numbers.
In a simulation utilizing random numbers you might want to recreate, you rerun the simulation with the same seed. It can be handy for tracking bugs when you want to regenerate a given faulty scenario as well - running your program with the exact same sequence of random numbers that crashed the program.
Random is not a random number generator, it is a deterministic pseudo-random sequence generator, which takes its name for historical reasons.
The reason to use System.Random is if you want these properties, namely a deterministic sequence, which is guaranteed to produce the same sequence of results when initialized with the same seed.
If you want to improve the "randomness" without sacrificing the interface, you can inherit from System.Random overriding several methods.
https://msdn.microsoft.com/en-us/library/system.random.sample(v=vs.110).aspx
Why would you want a deterministic sequence
One reason to have a deterministic sequence rather than true randomness is because it is repeatable.
For example, if you are running a numerical simulation, you can initialize the sequence with a (true) random number, and record what number was used.
Then, if you wish to repeat the exact same simulation, e.g. for debugging purposes, you can do so by instead initializing the sequence with the recorded value.
Why would you want this particular, not very good, sequence
The only reason I can think of would be for backwards compatibility with existing code which uses this class.
In short, if you want to improve the sequence without changing the rest of your code, go ahead.
If I don't need the security, i.e., I just want a relatively indeterminate value not one that's cryptographically strong, Random has a much easier interface to use.
Different needs call for different RNGs. For crypto, you want your random numbers to be as random as possible. For Monte Carlo simulations, you want them to fill the space evenly and to be able to start the RNG from a known state.
I wrote a game (Crystal Sliders on the iPhone: Here) that would put up a "random" series of gems (images) on the map and you would rotate the map how you wanted it and select them and they went away. - Similar to Bejeweled. I was using Random(), and it was seeded with the number of 100ns ticks since the phone booted, a pretty random seed.
I found it amazing that it would generate games that were nearly identical to each other -of the 90 or so gems, of 2 colors, I would get two EXACTLY the same except for 1 to 3 gems! If you flip 90 coins and get the same pattern except for 1-3 flips, that is VERY unlikely! I have several screen shots that show them the same. I was shocked at how bad System.Random() was! I assumed, that I MUST have written something horribly wrong in my code and was using it wrong. I was wrong though, it was the generator.
As an experiment - and a final solution, I went back to the random number generator that I've been using since 1985 or so - which is VASTLY better. It is faster, has a period of 1.3 * 10^154 (2^521) before it repeats. The original algorithm was seeded with a 16 bit number, but I changed that to a 32 bit number, and improved the initial seeding.
The original one is here:
ftp://ftp.grnet.gr/pub/lang/algorithms/c/jpl-c/random.c
Over the years, I've thrown every random number test I could think of at this, and it past all of them. I don't expect that it is of any value as a cryptographic one, but it returns a number as fast as "return *p++;" until it runs out of the 521 bits, and then it runs a quick process over the bits to create new random ones.
I created a C# wrapper - called it JPLRandom() implemented the same interface as Random() and changed all the places where I called it in the code.
The difference was VASTLY better - OMG I was amazed - there should be no way I could tell from just looking at the screens of 90 or so gems in a pattern, but I did an emergency release of my game following this.
And I would never use System.Random() for anything ever again. I'm SHOCKED that their version is blown away by something that is now 30 years old!
-Traderhut Games