如何在C#中生成随机整数?


当前回答

这是我使用的类。工作方式类似RandomNumber.GenerateRandom(1666)

internal static class RandomNumber
{
    private static Random r = new Random();
    private static object l = new object();
    private static Random globalRandom = new Random();
    [ThreadStatic]
    private static Random localRandom;
    public static int GenerateNewRandom(int min, int max)
    {
        return new Random().Next(min, max);
    }
    public static int GenerateLockedRandom(int min, int max)
    {
        int result;
        lock (RandomNumber.l)
        {
            result = RandomNumber.r.Next(min, max);
        }
        return result;
    }
    public static int GenerateRandom(int min, int max)
    {
        Random random = RandomNumber.localRandom;
        if (random == null)
        {
            int seed;
            lock (RandomNumber.globalRandom)
            {
                seed = RandomNumber.globalRandom.Next();
            }
            random = (RandomNumber.localRandom = new Random(seed));
        }
        return random.Next(min, max);
    }
}

其他回答

内置Random类(System.Random)生成的数字生成伪随机数。

如果你想要真正的随机数,我们最接近的就是“安全伪随机生成器”,它可以通过使用C#中的Cryptographic类(如RNGCryptoServiceProvider)生成。

即使如此,如果你仍然需要真正的随机数,你将需要使用一个外部源,比如解释放射性衰变的设备,作为随机数发生器的种子。因为,根据定义,任何纯算法产生的数字都不可能是真正随机的。

从这里修改答案。

如果您可以访问与Intel Secure Key兼容的CPU,则可以使用以下库生成真正的随机数和字符串:https://github.com/JebteK/RdRand和https://www.rdrand.com/

只需从这里下载最新版本,包括Jebtek.RdRand并为其添加一个using语句。然后,您需要做的就是:

// Check to see if this is a compatible CPU
bool isAvailable = RdRandom.GeneratorAvailable();

// Generate 10 random characters
string key       = RdRandom.GenerateKey(10);

 // Generate 64 random characters, useful for API keys 
string apiKey    = RdRandom.GenerateAPIKey();

// Generate an array of 10 random bytes
byte[] b         = RdRandom.GenerateBytes(10);

// Generate a random unsigned int
uint i           = RdRandom.GenerateUnsignedInt();

如果您没有兼容的CPU来执行代码,只需使用rdrand.com上的RESTful服务即可。使用项目中包含的RdRandom包装库,您只需要这样做(注册时可以获得1000个免费调用):

string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret   = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");

如果您希望CSRNG生成最小值和最大值之间的随机数,这是适合您的。它将使用安全的随机种子初始化随机类。

    class SecureRandom : Random
    {
        public static byte[] GetBytes(ulong length)
        {
            RNGCryptoServiceProvider RNG = new RNGCryptoServiceProvider();
            byte[] bytes = new byte[length];
            RNG.GetBytes(bytes);
            RNG.Dispose();
            return bytes;
        }
        public SecureRandom() : base(BitConverter.ToInt32(GetBytes(4), 0))
        {

        }
        public int GetRandomInt(int min, int max)
        {
            int treashold = max - min;
            if(treashold != Math.Abs(treashold))
            {
                throw new ArithmeticException("The minimum value can't exceed the maximum value!");
            }
            if (treashold == 0)
            {
                throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
            }
            return min + (Next() % treashold);
        }
        public static int GetRandomIntStatic(int min, int max)
        {
            int treashold = max - min;
            if (treashold != Math.Abs(treashold))
            {
                throw new ArithmeticException("The minimum value can't exceed the maximum value!");
            }
            if(treashold == 0)
            {
                throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
            }
            return min + (BitConverter.ToInt32(GetBytes(4), 0) % treashold);
        }
    }

我总是有生成随机数的方法,这些方法有助于实现各种目的。我希望这也能帮助您:

public class RandomGenerator  
{  
    public int RandomNumber(int min, int max)  
    {  
        var random = new Random();  
        return random.Next(min, max);  
    }  

    public string RandomString(int size, bool lowerCase)  
    {  
        var builder = new StringBuilder();  
        var random  = new Random();  
        char ch;  

        for (int i = 0; i < size; i++)  
        {  
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));  
            builder.Append(ch);  
        }  

        if (lowerCase)  
            return builder.ToString().ToLower();  
        return builder.ToString();  
    }  
}

请注意,新的Random()是在当前时间戳上播种的。

如果您只想生成一个数字,可以使用:

new Random().Next(int.MinValue,int.MaxValue)

有关更多信息,请查看Random类,但请注意:

然而,由于时钟具有有限的分辨率,使用无参数构造器来连续创建不同的随机对象会创建随机数生成器,生成相同的随机数序列

因此,不要使用此代码生成一系列随机数。