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

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

2867298 次浏览
Random r = new Random();int n = r.Next();

注意new Random()是当前时间戳上的种子。

如果你想生成只有一个号码,你可以使用:

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

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

但是,由于时钟具有有限分辨率,因此使用无参数构造函数连续创建不同的Random对象会创建产生相同随机数序列的随机数生成器

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

#0类用于创建随机数。(当然是伪随机的。)。

示例:

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

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

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

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

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

//Function to get random numberprivate static readonly Random getrandom = new Random();
public static int GetRandomNumber(int min, int max){lock(getrandom) // synchronize{return getrandom.Next(min, max);}}

修改后的答案这里

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

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

// Check to see if this is a compatible CPUbool isAvailable = RdRandom.GeneratorAvailable();
// Generate 10 random charactersstring key       = RdRandom.GenerateKey(10);
// Generate 64 random characters, useful for API keysstring apiKey    = RdRandom.GenerateAPIKey();
// Generate an array of 10 random bytesbyte[] b         = RdRandom.GenerateBytes(10);
// Generate a random unsigned intuint i           = RdRandom.GenerateUnsignedInt();

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

string ret = Randomizer.GenerateKey(<length>, "<key>");uint ret   = Randomizer.GenerateUInt("<key>");byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
Random rand = new Random();int name = rand.Next()

把你想要的任何值放在第二个括号中确保您已经通过编写prop和双选项卡来设置名称以生成代码

虽然这是好的:

Random random = new Random();int randomNumber = random.Next()

大多数时候你都想控制极限(最小和最大数字)。所以你需要指定随机数的开始和结束位置。

Next()方法接受两个参数,min和max。

所以如果我想让我的随机数在5到15之间我就这么做

int randomNumber = random.Next(5, 16)

这是我使用的类。像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);}}

我已经尝试了所有这些解决方案,不包括COBOL答案… lol

这些解决方案都不够好。我需要快速的for 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);}

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

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

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

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

尝试这些简单的步骤来创建随机数:

创建函数:

private int randomnumber(int min, int max){Random rnum = new Random();return rnum.Next(min, max);}

在要使用随机数的位置使用上述函数。假设您要在输入框中使用它。

textBox1.Text = randomnumber(0, 999).ToString();

0是最小值,999是最大值。您可以将值更改为任何您想要的值。

创建一个随机对象

Random rand = new Random();

并使用它

int randomNumber = rand.Next(min, max);

你不必每次需要一个随机数时都初始化new Random(),初始化一个Random,然后在循环或其他什么中根据需要多次使用它

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

RNGCryptoServiceProvider类(MSDNdotnetperls

它实现了IDisposable。

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

由计算机通过确定性过程计算的数字,根据定义,不能是随机的。

如果你想要一个真正的随机数,随机性来自大气噪声或放射性衰变。

您可以尝试例如RANDOM.ORG(它会降低性能)

为什么不使用int randomNumber = Random.Range(start_range, end_range)

我想演示每次使用新的随机生成器时会发生什么。假设你有两个方法或两个类,每个都需要一个随机数。你天真地对它们编码如下:

public class A{public A(){var rnd=new Random();ID=rnd.Next();}public int ID { get; private set; }}public class B{public B(){var rnd=new Random();ID=rnd.Next();}public int ID { get; private set; }}

你认为你会得到两个不同的ID吗?NOPE

class Program{static void Main(string[] args){A a=new A();B b=new B();
int ida=a.ID, idb=b.ID;// ida = 1452879101// idb = 1452879101}}

解决方案是总是使用单个静态随机生成器。像这样:

public static class Utils{public static readonly Random random=new Random();}
public class A{public A(){ID=Utils.random.Next();}public int ID { get; private set; }}public class B{public B(){ID=Utils.random.Next();}public int ID { get; private set; }}

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

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

我鼓励您观看这个视频,它深入了解了使用C#https://www.youtube.com/watch?v=tCYxc-2-3fY的随机性哲学

首先让我们了解随机的哲学。当我们告诉一个人在红色、绿色和黄色之间做出选择时,内部会发生什么。是什么让一个人选择红色、黄色或绿色?

c#Random

一些最初的想法进入人的头脑,决定他的选择,它可以是最喜欢的颜色,幸运色等。换句话说,一些初始触发,我们在随机中称之为种子。这个种子是起点,触发他选择随机值。

现在,如果种子易于猜测,那么这些随机数被称为,当种子难以猜测时,这些随机数被称为担保随机数。

例如,一个人根据天气和声音组合选择是颜色,那么很难猜出最初的种子。

c#Random

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

*“Random”类仅生成PSEUDO随机数,要生成SECURE随机数,我们需要使用“RNGCryptoServiceProvider”类。

c#Random

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

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

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

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

您还可以为Next()函数指定最小值和最大值。比如:

 int n = new Random().Next(5, 10);
Random random = new Random ();int randomNumber = random.Next (lowerBound,upperBound);

快速简单的内联,使用以下代码:

new Random().Next(min, max);
// for example unique namestrName += "_" + new Random().Next(100, 999);

我会假设你想要一个像下面这样的均匀分布的随机数生成器。大多数编程语言中的随机数,包括C#和C++在使用它们之前都没有正确地打乱。这意味着你会一遍又一遍地得到相同的数字,这不是真正的随机。为了避免一遍又一遍地绘制相同的数字,你需要一个种子。通常,时间滴答对这项任务来说是可以的。记住,如果你每次都使用相同的种子,你会一遍又一遍地得到相同的数字。所以尽量使用不同的种子。时间是种子的良好来源,因为它们总是变化。

int GetRandomNumber(int min, int max){Random rand = new Random((int)DateTime.Now.Ticks);return rand.Next(min, max);}

如果您正在寻找正态分布的随机数生成器,您可能会使用Box-Muller转换。检查随机高斯变量问题中的yeyeyoosef的答案。由于您想要整数,因此必须在末尾将双值转换为整数。

Random rand = new Random(); //reuse this if you are generating manydouble u1 = 1.0-rand.NextDouble(); //uniform(0,1] random doublesdouble u2 = 1.0-rand.NextDouble();double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)double randNormal =mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)

随机高斯变量

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

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

对于强随机种子,我总是使用CryptoRNG而不是Time。

using System;using System.Security.Cryptography;
public class Program{public static void Main(){var random = new Random(GetSeed());Console.WriteLine(random.Next());}
public static int GetSeed(){using (var rng = new RNGCryptoServiceProvider()){var intBytes = new byte[4];rng.GetBytes(intBytes);return BitConverter.ToInt32(intBytes, 0);}}}

重复使用Random的一个实例

// Somewhat better code...Random rng = new Random();for (int i = 0; i < 100; i++){Console.WriteLine(GenerateDigit(rng));}...static int GenerateDigit(Random rng){// Assume there'd be more logic here reallyreturn rng.Next(10);}

本文将探讨为什么随机性会导致如此多的问题,以及如何解决这些问题。http://csharpindepth.com/Articles/Chapter12/Random.aspx

对不起,OP确实需要一个随机的#0值,但是为了分享知识,如果你想要一个随机的BigInteger值,你可以使用以下语句:

BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));

只是作为将来参考的注释。

如果您使用的是. NET Core,多个Random实例并不像以前那样危险。我知道这个问题来自2010年,但由于这个问题很老但有一定的吸引力,我认为记录一下变化是一件好事。

你可以参考我不久前提出的这个问题:

微软是否更改了随机默认种子?

基本上,他们已经将默认种子从Environment.TickCount更改为Guid.NewGuid().GetHashCode(),因此如果您创建了2个Random实例,它不应该显示相同的数字(1:40亿)。

您可以在此处看到与. NET Framework/. NET Core(2.0.0+)不同的文件:https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d

它不像RNGCryptoServiceProvider那样安全,但至少它不会给你奇怪的结果。


@神秘主义:

这现在已经过时了。对使用Guid有相当大的反对。代码现在是Interop. GetR的((byte*)&结果, sizeof(int));

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

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

有许多实用函数或服务可以更好地以与System. Random相同的方式缓存,因此它适合于泛型实现:

static public class CachedService<T> where T : new() {static public T Get { get; } = new T();}

随机:用于随机(或类似):

CachedService<System.Random>.Get.Next(999);

如其他答案中所述,一个好的安全方法是使用安全加密生成器。这里的所有示例都显示了RNGCryptoServiceProvider的用法,与我建议的解决方案相比,它正在编写长代码。

使用随机数生成器写在密码学API的顶部。它与RNGCryptoServiceProvider一样安全,具有相同的随机性。

// Gives a random number for the integer range.// You can simply update the parameters as your needs.RandomNumberGenerator.GetInt32(int.MinValue, int.MaxValue);
Random r=new Random();int Numbers=r.next(min value, max value);