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

Rella 1792 c# random

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

Guffa.. 2348

Random用于创建随机数.(当然是伪随机的.).

例:

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

如果要创建多个随机数,则应保留Random实例并重复使用它.如果您创建新实例的时间太近,它们将生成与随机生成器从系统时钟播种相同的随机数序列.

  • 对于Unity C#用户只需注意,您必须指定"System.Random()",因为Unity有一个"UnityEngine.Random()"冲突(注意"UnityEngine.Random()"无法生成随机号).由于统一并不总是默认导入系统,这可能会引起一些混乱. (144认同)
  • 我认为添加免责声明这不是加密安全是有用的,因为这是一个流行的问题,以防有人盲目地尝试用"随机"进行密码学... (4认同)
  • @JuniorM:是的,你可以使它是静态的重用它,但是你必须要小心,这样你就不会从多个线程访问它,因为它不是线程安全的(正如任何没有专门设置线程安全的类一样) ). (3认同)
  • 为了重用它,您可以将rnd声明为static并/或在初始化代码时将其设置一次。 (2认同)

Shivprasad K.. 248

问题看起来很简单,但答案有点复杂.如果你看到几乎每个人都建议使用Random类,有些人建议使用RNG加密类.但是什么时候选择什么.

为此,我们首先需要理解"随机性"一词及其背后的哲学.

我鼓励你观看这段视频,该视频深入探讨了随机使用C#https://www.youtube.com/watch?v= tCYxc-2-3fY

首先让我们了解RANDOMNESS的哲学.当我们告诉一个人在RED,GREEN和YELLOW之间做出选择时会发生什么.是什么让人选择RED或YELLOW或GREEN?

c#随机

最初的想法是进入决定他选择的人的心灵,它可以是喜欢的颜色,幸运的颜色等.换句话说,我们将RANDOM中的一些初始触发器称为SEED.此SEED是起始点,触发器促使他选择RANDOM值.

现在,如果SEED易于猜测,那么这些随机数被称为PSEUDO,当种子难以猜测时,这些随机数被称为 SECURED随机数.

例如,一个人根据天气和声音组合选择颜色,那么很难猜测初始种子.

c#随机

现在让我作一个重要的声明: -

*"Random"类仅生成PSEUDO随机数并生成SECURE随机数,我们需要使用"RNGCryptoServiceProvider"类.

c#随机

随机类从您的CPU时钟获取种子值,这是非常可预测的.所以换句话说,CAND的RANDOM类生成伪随机数,下面是相同的代码.

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

而RNGCryptoServiceProvider类使用OS熵来生成种子.OS熵是一个随机值,它是使用声音,鼠标点击和键盘时序,热温等生成的.下面是相同的代码.

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

要了解操作系统熵,请参阅此视频,请访问14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY,其中解释了操作系统熵的逻辑.因此,使用简单的单词RNG Crypto会生成SECURE随机数.

  • shouldn't be your byte[5] only [4] as ToInt32 parses only 4 bytes? (8认同)
  • 了解这些课程的住所在总是有帮助的。系统安全密码学 (5认同)

Pankaj Mishr.. 223

每次执行新的Random()时都会初始化.这意味着在紧密循环中,您可以多次获得相同的值.您应该保留一个Random实例并继续在同一个实例上使用Next.

//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);
    }
}

  • 这是一个实现,它将代码与seval线程同步使用.这对多线程应用程序很有用,但对单线程应用程序来说浪费时间. (22认同)
  • 这不是@Guffa在6个月前的回答中所说的吗?"如果您创建新实例的时间太近,它们将生成相同系列的随机数" (3认同)
  • @Chris-你说得对.在这里我提供了实现.我认为这是一个很好的方式.它效果更好. (3认同)

Fyodor Soiki.. 86

注意new Random()在当前时间戳上播种.

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

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

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

但是,由于时钟具有有限的分辨率,使用无参数构造函数以紧密连续的方式创建不同的随机对象会创建随机数生成器,从而生成相同的随机数序列

所以不要使用此代码生成一系列随机数.

  • -1:默认种子基于时间; 在循环中执行此操作,您将获得非常随机的结果.您应该创建**一个**生成器并将其用于所有数字,而不是每次都使用单独的生成器. (38认同)
  • 好的,公平的.撤销.虽然,我仍然认为在循环中不使用`new Random()`是一个重点. (25认同)
  • 嘿,那太不公平了.问题是如何生成随机int数.没有提到循环或系列. (18认同)

Joren.. 48

Random r = new Random();
int n = r.Next();


小智.. 27

我想添加一个加密安全版本:

RNGCryptoServiceProvider类(MSDNdotnetperls)

它实现了IDisposable.

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
   byte[] randomNumber = new byte[4];//4 for int32
   rng.GetBytes(randomNumber);
   int value = BitConverter.ToInt32(randomNumber, 0);
}


mbcrump.. 16

您可以在他为伪随机数构建的MiscUtil类库中使用Jon Skeet的StaticRandom方法.

using MiscUtil;
...

for (int i = 0; i < 100; 
    Console.WriteLine(StaticRandom.Next());

  • 我刚看了一下源代码,这个函数使用完全相同的随机数引擎,C#中的"包含"引擎,但确保所有调用使用相同的"种子"/"母对象".(对不起,我不知道C#术语.但我的观点是,这个函数没有比标准函数更好的随机数.) (26认同)
  • 任何东西都不可能是"真正随机的",因为它总是存在一些限制因素或偏见,这是其存在所固有的.你没有在科学课上听老师讲课吗?;-) (5认同)

Mohamed Seli.. 14

最好用当前的毫秒种子Random对象,以确保真正的随机数,你几乎不会发现多次使用它的重复

Random rand = new Random(DateTime.Now.Millisecond);

更新

我知道new Random()使用当前的滴答作为种子,但播种当前毫秒仍然足够好,因为它是良好的随机启动

最后一点是你不必new Random()每次需要一个随机数时初始化,启动一个Random对象然后在循环内或其他任何时候使用它多次

  • 这是积极的坏事.DateTime.Now.Millisecond(与DateTime.Now.Ticks不同)是介于0和999之间的数字.如果您为每个随机数创建一个新数字,则只有1000种可能性. (7认同)
  • `new Random()`使用当前的tick作为种子.当您在相同的毫秒内(而不是勾选)实例化多个实例时,您将获得返回的相同值. (4认同)

Proximo.. 13

我已经尝试了所有这些解决方案,不包括COBOL答案...大声笑

这些解决方案都不够好.我需要在快速的int循环中使用random,即使在很宽的范围内,我也会获得大量的重复值.在解决了一段随机结果后,我决定一劳永逸地解决这个问题.

这都是关于种子的.

我通过解析Guid中的非数字来创建一个随机整数,然后我用它来实例化我的Random类.

public int GenerateRandom(int min, int max)
{
    var seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
    return new Random(seed).Next(min, max);
}

更新:如果您实例化一次Random类,则无需播种.因此,最好创建一个静态类并从中调用一个方法.

public static class IntUtil
{
   private static Random random;

   private static void Init()
   {
      if (random == null) random = new Random();
   }

   public static int Random(int min, int max)
   {
      Init();
      return random.Next(min, max);
   }
}

然后你可以像这样使用静态类.

for(var i = 0; i < 1000; i++)
{
   int randomNumber = IntUtil.Random(1,100);
   Console.WriteLine(randomNumber); 
}

我承认我更喜欢这种方法.

  • Guid不是随机的,它不是一个好种子.GUID不保证随机性,它保证了唯一性.http://stackoverflow.com/questions/2621563/how-random-is-system-guid-newguid-take-two (4认同)

JebaDaHut.. 10

这里修改答案。

如果您有权访问兼容Intel Secure Key的CPU,则可以使用以下库生成实际的随机数和字符串:https : //github.com/JebteK/RdRandhttps://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>");


小智.. 9

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

如果你想要真正的随机数,我们可以得到的最接近的是"安全伪随机生成器",它可以通过使用C#中的加密类生成RNGCryptoServiceProvider.

即便如此,如果您仍然需要真正的随机数,您将需要使用外部源,例如考虑放射性衰变的设备作为随机数生成器的种子.因为,根据定义,纯粹算法手段产生的任何数字都不能真正随机.


shA.t.. 8

我使用下面的代码来获得一个随机数:

var random = new Random((int)DateTime.Now.Ticks);
var randomValue = random.Next(startValue, endValue + 1);


小智.. 5

这是我使用的课程。像RandomNumber.GenerateRandom(1, 666)

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);
    }
}


归档时间:

查看次数:

2158243 次

最近记录:

10 月,4 周 前