提问人:Rella 提问时间:4/25/2010 最后编辑:ADJenksRella 更新时间:3/8/2023 访问量:3038387
如何在 C# 中生成随机整数?
How do I generate a random integer in C#?
答:
Random r = new Random();
int n = r.Next();
评论
请注意,在当前时间戳上播种。new Random()
如果您只想生成一个数字,您可以使用:
new Random().Next( int.MinValue, int.MaxValue )
有关更多信息,请查看 Random 类,但请注意:
但是,由于时钟具有有限的分辨率,因此使用无参数构造函数连续创建不同的 Random 对象会创建随机数生成器,这些随机数生成器会生成相同的随机数序列
所以不要用这段代码来生成一系列随机数。
评论
new Random()
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
评论
rnd
static
Random
Random
rnd.Next(1,13)
您可以在 Jon Skeet 为伪随机数构建的 MiscUtil 类库中使用 StaticRandom 方法。
using MiscUtil;
...
for (int i = 0; i < 100;
Console.WriteLine(StaticRandom.Next());
评论
每次执行时,都会对其进行初始化。这意味着在紧密循环中,您多次获得相同的值。您应该保留单个实例并继续在同一实例上使用。new 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);
}
}
评论
Random
从这里修改答案。
如果您有权访问兼容 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>");
Random rand = new Random();
int name = rand.Next()
将所需的任何值放在第二个括号中 确保你已通过编写 prop 和 double tab 来设置名称以生成代码
评论
虽然这没关系:
Random random = new Random();
int randomNumber = random.Next()
大多数时候,您都希望控制限制(最小和最大 mumbers)。因此,您需要指定随机数的开始和结束位置。
该方法接受两个参数:min 和 max。Next()
因此,如果我希望我的随机数介于 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 答案......哈哈
这些解决方案都不够好。我需要在快速 for int 循环中使用随机数,即使在非常宽的范围内,我也会得到大量重复值。在满足于这种随机结果太久之后,我决定最终一劳永逸地解决这个问题。
这一切都与种子有关。
我通过解析 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);
}
我承认我更喜欢这种方法。
评论
内置类 (System.Random) 生成的数字生成伪随机数。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 对象
Random rand = new Random();
并使用它
int randomNumber = rand.Next(min, max);
你不必每次都需要一个随机数时都初始化,启动一个随机数,然后在循环中根据需要多次使用它new Random()
评论
new Random()
使用当前分时作为种子。当您在同一毫秒内实例化多个实例(而不是 tick)时,您将返回相同的值。
我想添加一个加密安全的版本:
RNGCryptoServiceProvider 类(MSDN 或 dotnetperls)
它实现 IDisposable。
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] randomNumber = new byte[4];//4 for int32
rng.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; }
}
你认为你会得到两个不同的身份证吗?不
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; }
}
评论
RNGCryptoServiceProvider
这个问题看起来很简单,但答案有点复杂。如果你看到,几乎每个人都建议使用 Random 类,有些人建议使用 RNG 加密类。但是什么时候选择什么。
为此,我们需要首先了解“随机性”一词及其背后的哲学。
我鼓励您观看我制作的这个视频,该视频深入探讨了使用 C# 的随机性哲学 https://www.youtube.com/watch?v=tCYxc-2-3fY
首先让我们了解随机性的哲学。当我们告诉一个人在红色、绿色和黄色之间做出选择时,内部会发生什么。是什么让一个人选择红色、黄色或绿色?
一些最初的想法进入了决定他选择的人的脑海中,它可以是最喜欢的颜色、幸运的颜色等等。换句话说,一些初始触发器,我们在 RANDOM 中将其称为 SEED。这个 SEED 是起点,是促使他选择 RANDOM 值的触发器。
现在,如果 SEED 很容易猜到,那么这些随机数被称为 PSEUDO,当种子难以猜测时,这些随机数被称为 SECURED 随机数。
例如,一个人根据天气和声音组合选择颜色,那么就很难猜出最初的种子。
现在让我做一个重要的声明:
*“Random”类只生成伪随机数,要生成SECURE随机数,我们需要使用“RNGCryptoServiceProvider”类。
Random 类从 CPU 时钟中获取种子值,这是非常可预测的。所以换句话说,C#的RANDOM类生成伪随机数,下面是相同的代码。
Random random = new Random();
int randomNumber = random.Next();
而该类使用 OS 熵来生成种子。操作系统熵是一个随机值,它是使用声音、鼠标点击和键盘时序、热温度等生成的。下面是相同的代码。RNGCryptoServiceProvider
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 随机数。
评论
RandomNumberGenerator.Create()
RNGCryptoServiceProvider
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 name
strName += "_" + 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 变换。在随机高斯变量问题中查看 yoyoyoyosef 的答案。由于您需要整数,因此必须在末尾将双倍值转换为整数。
Random rand = new Random(); //reuse this if you are generating many
double u1 = 1.0-rand.NextDouble(); //uniform(0,1] random doubles
double 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);
}
}
}
评论
RNGCryptoServiceProvider
重复使用一个 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 really
return rng.Next(10);
}
本文将探讨为什么随机性会导致如此多的问题,以及如何解决这些问题。http://csharpindepth.com/Articles/Chapter12/Random.aspx
评论
Random
不是线程安全类。如果创建单个实例,则应在锁定机制后面限制对该实例的访问。
对不起,OP 确实需要一个随机的 int
值,但为了分享知识的简单目的,如果你想要一个随机值,你可以使用以下语句:BigInteger
BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));
评论
byte[] bytes = new byte[byteCount]; random.NextBytes(bytes); BigInteger value = new BigInteger(bytes);
Random.Next((int) '0', ((int) '9') + 1)
string
Guid
NewGuid
仅供将来参考。
如果使用的是 .NET Core,则多个随机实例不会像以前那样危险。我知道这个问题是 2010 年的,但由于这个问题很老,但有一些吸引力,我认为记录变化是一件好事。
你可以参考我刚才提出的这个问题:
基本上,他们已将默认种子从 更改为 ,因此如果您创建 2 个 Random 实例,它不应显示相同的数字(1:4 亿)。Environment.TickCount
Guid.NewGuid().GetHashCode()
可以在此处查看文件与 .NET Framework/.NET Core (2.0.0+) 的差异:https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d
它不像 RNGCryptoServiceProvider 安全,但至少它不会给你奇怪的结果。
按@Enigmativity:
这现在已经过时了。对使用 Guids 有相当大的反对。代码现在是 Interop.GetRandomBytes((byte*)&result, sizeof(int));
评论
Interop.GetRandomBytes((byte*)&result, sizeof(int));
如果您希望 CSRNG 生成最小值和最大值之间的随机数,这是为您准备的。它将使用安全的随机种子初始化类。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 之上的 RandomNumberGenerator。它与相同的随机性一样安全。RNGCryptoServiceProvider
// Gives a random number for the integer range.
// You can simply update the parameters as your needs.
RandomNumberGenerator.GetInt32(int.MinValue, int.MaxValue);
评论
RNGCryptoServiceProvider
[Obsolete()]
RandomNumberGenerator
Random r=new Random();
int Numbers=r.next(min value, max value);
评论
Next
next
r.Next(minValue, maxValue);
maxValue - 1
Numbers
Random
该类用于生成伪随机数。
一个例子可能是这样的:Random
public int GenRandom(int minimum, int maximum)
{
Random random = new Random();
int result = random.Next(minimum - 1, maximum + 1);
return result;
}
我添加了最小值和最大值,因为该函数永远无法达到 和 .1
Next(int, int)
minimum
maximum
再看看这个,将是一个随机数猜测者:
class Program
{
static void Main(string[] args)
{
int i = 0;
while (true)
{
if (i < 1)
{
Console.Write("Minimum value: ");
int min = int.Parse(Console.ReadLine());
Console.Write("Maximum value: ");
int max = int.Parse(Console.ReadLine());
Random random = new Random();
}
int randomNumber = random.Next(min, max);
Console.Write("Enter a guess: ");
if (int.Parse(Console.ReadLine()) == randomNumber)
{
Console.WriteLine("Congrats! You won!");
Console.ReadKey();
return;
}
else
Console.WriteLine("Hmm, give it another guess!"); return;
}
}
}
在 .NET 6 中,可以使用 Random.Shared:
int random = Random.Shared.Next();
在 .NET 8 预览版中,该类添加了许多新的缺失方法,例如随机随机数组等。
评论