Categories
c# random

How do I generate a random integer in C#?

2281

How do I generate a random integer in C#?

1

  • 1

    See this answer for the current (and easiest) cryptographically secure solution

    – Mafii

    Jul 12 at 8:10


2882

The Random class is used to create random numbers. (Pseudo-random that is of course.).

Example:

Random rnd = new Random();
int month  = rnd.Next(1, 13);  // creates a number between 1 and 12
int dice   = rnd.Next(1, 7);   // creates a number between 1 and 6
int card   = rnd.Next(52);     // creates a number between 0 and 51

If you are going to create more than one random number, you should keep the Random instance and reuse it. If you create new instances too close in time, they will produce the same series of random numbers as the random generator is seeded from the system clock.

15

369

The question looks very simple but the answer is bit complicated. If you see almost everyone has suggested to use the Random class and some have suggested to use the RNG crypto class. But then when to choose what.

For that we need to first understand the term RANDOMNESS and the philosophy behind it.

I would encourage you to watch this video which goes in depth in the philosophy of RANDOMNESS using C# https://www.youtube.com/watch?v=tCYxc-2-3fY

First thing let us understand the philosophy of RANDOMNESS. When we tell a person to choose between RED, GREEN and YELLOW what happens internally. What makes a person choose RED or YELLOW or GREEN?

c# Random

Some initial thought goes into the persons mind which decides his choice, it can be favorite color , lucky color and so on. In other words some initial trigger which we term in RANDOM as SEED.This SEED is the beginning point, the trigger which instigates him to select the RANDOM value.

Now if a SEED is easy to guess then those kind of random numbers are termed as PSEUDO and when a seed is difficult to guess those random numbers are termed SECURED random numbers.

For example a person chooses is color depending on weather and sound combination then it would be difficult to guess the initial seed.

c# Random

Now let me make an important statement:-

*“Random” class generates only PSEUDO random number and to generate SECURE random number we need to use “RNGCryptoServiceProvider” class.

c# Random

Random class takes seed values from your CPU clock which is very much predictable. So in other words RANDOM class of C# generates pseudo random numbers , below is the code for the same.

var random = new Random();
int randomnumber = random.Next()

While the RNGCryptoServiceProvider class uses OS entropy to generate seeds. OS entropy is a random value which is generated using sound, mouse click, and keyboard timings, thermal temp etc. Below goes the code for the same.

using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider()) 
{ 
    byte[] rno = new byte[5];    
    rg.GetBytes(rno);    
    int randomvalue = BitConverter.ToInt32(rno, 0); 
}

To understand OS entropy see this video from 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY where the logic of OS entropy is explained. So putting in simple words RNG Crypto generates SECURE random numbers.

5

  • 14

    shouldn’t be your byte[5] only [4] as ToInt32 parses only 4 bytes?

    – Bernhard

    Nov 21, 2017 at 11:34


  • 10

    It’s always helpful to know where these classes live. System.Security.Cryptography

    – Elton

    Dec 18, 2018 at 23:49

  • 6

    It is recommended to use RandomNumberGenerator.Create() instead of calling the constructor of RNGCryptoServiceProvider since it is not available on all platforms.

    Oct 17, 2019 at 18:35

  • I want just to precise that SecureRandom IS pseudo random generation.

    – Nùménor

    Jan 29, 2020 at 16:30

  • Due to the increased randomness of the seed, is it OK to create new RNGCryptoServiceProvider objects each time I need to generate a random number, or is it still better to create one RNGCryptoServiceProvider object and reuse it whenever I need to generate a random number, as should be done with the Random class?

    Mar 23, 2020 at 17:24

264

Every time you do new Random() it is initialized. This means that in a tight loop you get the same value lots of times. You should keep a single Random instance and keep using Next on the same instance.

//Function to get random number
private static readonly Random getrandom = new Random();

public static int GetRandomNumber(int min, int max)
{
    lock(getrandom) // synchronize
    {
        return getrandom.Next(min, max);
    }
}

5

  • 5

    Is this not what @Guffa said in his answer 6 months ago? “If you create new instances too close in time, they will produce the same series of random numbers”

    – Chris

    Oct 4, 2010 at 12:00

  • 4

    @Chris- That’s right what you said. In this I have provided the implementation of that. I think it’s a good way of doing it. It works better.

    Oct 4, 2010 at 14:16

  • 24

    This is an implementation that synchronises the code for use from seval threads. That is good for a multi threaded application, but a waste of time for a single threaded application.

    – Guffa

    Feb 26, 2013 at 0:05


  • @SeanWorle: First, I tried it with the approach from Guffa. Then I tried to store the same Random object. At both cases I got the same random number. With the approach from Pankaj it didn’t happen. Perhaps this is random, but I doubt it now. I’m querying for the random number in the same second from different threads.

    – testing

    Sep 12, 2017 at 16:26

  • 3

    @testing: I agree that Pankaj’s method is the correct one to use. What I’m saying is that it can be simplified to this: //Function to get random number private static readonly Random getrandom = new Random(); public static int GetRandomNumber(int min, int max) { lock(getrandom ) { // synchronize return getrandom.Next(min, max); } }

    Sep 14, 2017 at 1:51