public class RandomGenerator
{
public int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
public string RandomString(int size, bool lowerCase)
{
StringBuilder builder = new StringBuilder();
Random 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();
}
}
9
重复使用一个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);
}
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 实例并重复使用它 . 如果您创建新实例的时间太近,它们将生成相同系列的随机数,因为随机生成器是从系统时钟播种的 .
0
尝试这些简单的步骤来创建随机数:
Create function:
private int randomnumber(int min, int max)
{
Random rnum = new Random();
return rnum.Next(min, max);
}
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)
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);
}
}
13
虽然这没关系:
Random random = new Random();
int randomNumber = 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);
}
}
-1
对于强随机种子,我总是使用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);
}
}
}
1
为什么不使用 int randomNumber = Random.Range(start_range, end_range) ?
-3
对不起,OP确实需要一个随机 int 值,但出于简单的目的,如果你想要一个随机 BigInteger 值,你可以使用以下语句来分享知识:
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] randomNumber = new byte[4];//4 for int32
rng.GetBytes(randomNumber);
int value = BitConverter.ToInt32(randomNumber, 0);
}
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; }
}
你认为你会得到两个不同的身份证吗? 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; }
}
-1
我使用下面的代码来获得一个随机数:
var random = new Random((int)DateTime.Now.Ticks);
var randomValue = random.Next(startValue, endValue + 1);
11
内联快速简便,使用以下代码:
new Random().Next(min, max);
// for example unique name
strName += "_" + new Random().Next(100, 999);
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[5];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
}
Random rand = new Random(DateTime.Now.Millisecond);
Update
我知道 new Random() 使用当前的滴答作为种子,但是用当前的毫秒播种仍然足够好,因为它是随机启动的好
最后一点是你不必每次需要一个随机数时初始化 new Random() ,启动一个Random对象,然后在循环内需要多次使用它或者其他
197
int n = new Random().Next();
您还可以为 Next() 函数提供最小值和最大值 . 喜欢
int n = new Random().Next(5,10);
4
计算机通过确定性过程计算的数字,根据定义,不能是随机的 .
如果你想要一个真正的随机数,随机性来自大气噪声或放射性衰变 .
您可以尝试例如RANDOM.ORG(它会降低性能)
6
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);
2040
Random rand = new Random();
int name = rand.Next()
在第二个括号中放置您想要的任何值,确保通过编写prop和double选项卡来设置名称以生成代码
1
您可以使用下面的随机种子值尝试:
var rnd = new Random(11111111); //note: seed value is 11111111
string randomDigits = rnd.Next().ToString().Substring(0, 8);
var requestNumber = $"SD-{randomDigits}";
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);
}
Update :播种不是't necessary if you instantiate the Random class once. So it' d最好创建一个静态类并调用一个方法 .
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);
}
bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU
string key = RdRandom.GenerateKey(10); //Generate 10 random characters
string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys
byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes
uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int
string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
using System;
using MiscUtil;
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(StaticRandom.Next());
}
}
}
28 回答
我总是有方法生成随机数,这有助于各种目的 . 我希望这对你也有帮助:
重复使用一个Random实例
本文将介绍为什么随机性会导致如此多的问题,以及如何解决这些问题 . http://csharpindepth.com/Articles/Chapter12/Random.aspx
Random class用于创建随机数 . (当然是伪随机的 . ) .
例:
如果要创建多个随机数,则应保留
Random
实例并重复使用它 . 如果您创建新实例的时间太近,它们将生成相同系列的随机数,因为随机生成器是从系统时钟播种的 .尝试这些简单的步骤来创建随机数:
Create function:
在要使用随机数的位置使用上述功能 . 假设您要在文本框中使用它 .
0表示最小值,999表示最大值 . 您可以将值更改为您想要的任何值 .
我假设您需要一个均匀分布的随机数生成器,如下所示 . 大多数编程语言(包括C#和C)中的随机数在使用之前未正确洗牌 . 这意味着您将反复获得相同的数字,这实际上并不是随机的 . 为避免反复绘制相同的数字,需要种子 . 通常,时间刻度可以用于此任务 . 请记住,如果每次使用相同的种子,您将反复获得相同的数字 . 所以总是尝试使用不同的种子 . 时间是种子的良好来源,因为它们总是在变化 .
如果您正在寻找正态分布的随机数生成器,您可以使用Box-Muller转换 . 通过yoyoyoyosef在随机高斯变量问题中检查答案 . 由于您需要整数,因此必须在结尾处将double值转换为整数 .
Random Gaussian Variables
内置
Random
类(System.Random)生成的数字生成伪随机数 .如果你想要真正的随机数,我们可以得到的最接近的是"secure Pseudo Random Generator",这可以通过使用C#中的加密类来生成,例如
RNGCryptoServiceProvider
.即便如此,如果您仍然需要真正的随机数,您将需要使用外部源,例如考虑放射性衰变的设备作为随机数生成器的种子 . 因为,根据定义,纯粹算法手段生成的任何数字都不能真正随机 .
这是我使用的课程 . 像
RandomNumber.GenerateRandom(1, 666)
的作品虽然这没关系:
您想要在大多数时间控制限制(最小和最大数量) . 因此,您需要指定随机数的开始和结束位置 .
Next()
方法接受两个参数,min和max .所以,如果我希望我的随机数在5到15之间,我就是这么做的
请注意
new Random()
是在当前时间戳上播种的 .如果要生成 just one number ,可以使用:
new Random().Next( int.MinValue, int.MaxValue )
有关更多信息,请查看Random课程,但请注意:
所以不要使用此代码生成一系列随机数 .
每次执行新的Random()时都会初始化 . 这意味着在紧密循环中,您可以多次获得相同的值 . 您应该保留一个Random实例并继续在同一实例上使用Next .
对于强随机种子,我总是使用CryptoRNG而不是Time .
为什么不使用
int randomNumber = Random.Range(start_range, end_range)
?对不起,OP确实需要一个随机 int 值,但出于简单的目的,如果你想要一个随机
BigInteger
值,你可以使用以下语句来分享知识:我想添加一个加密安全版本:
RNGCryptoServiceProvider类(MSDN或dotnetperls)
它实现了IDisposable .
我想证明每次使用新的随机生成器时会发生什么 . 假设您有两个方法或两个类,每个类都需要一个随机数 . 你天真地对它们进行编码,如:
你认为你会得到两个不同的身份证吗? NOPE
解决方案是始终使用单个静态随机生成器 . 像这样:
我使用下面的代码来获得一个随机数:
内联快速简便,使用以下代码:
问题看起来很简单,但答案有点复杂 . 如果你看到几乎每个人都建议使用Random类,有些人建议使用RNG加密类 . 但是什么时候选择什么 .
为此,我们首先需要理解“随机性”一词及其背后的哲学 .
我鼓励你观看这段视频,该视频深入探讨使用C#https://www.youtube.com/watch?v=tCYxc-2-3fY的随机性哲学
首先让我们了解RANDOMNESS的哲学 . 当我们告诉一个人在RED,GREEN和YELLOW之间做出选择时会发生什么 . 是什么让一个人选择RED或YELLOW或GREEN?
一些最初的想法进入了人决定他选择的心灵,可以是喜欢的颜色,幸运的颜色等 . 换句话说,我们在RANDOM中称为SEED的初始触发器 . 这个SEED是起点,触发器促使他选择RANDOM值 .
现在,如果SEED易于猜测,那么这些随机数被称为 PSEUDO ,当种子难以猜测时,这些随机数被称为 SECURED 随机数 .
例如,一个人根据天气和声音组合选择颜色,那么很难猜测初始种子 .
现在让我作一个重要的声明: -
*“Random”类仅生成PSEUDO随机数并生成SECURE随机数,我们需要使用“RNGCryptoServiceProvider”类 .
随机类从您的CPU时钟获取种子值,这是非常可预测的 . 所以换句话说,RANDOM类的C#生成伪随机数,下面是相同的代码 .
而RNGCryptoServiceProvider类使用OS熵来生成种子 . OS熵是一个随机值,它是使用声音,鼠标点击和键盘时序,热温等生成的 . 下面是相同的代码 .
要了解OS熵,请参阅14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY中的视频,其中解释了OS熵的逻辑 . 因此,使用简单的单词RNG Crypto会生成SECURE随机数 .
最好用当前的毫秒为Random对象播种,以确保真正的随机数,并且你几乎不会多次使用它找到重复项
Update
我知道
new Random()
使用当前的滴答作为种子,但是用当前的毫秒播种仍然足够好,因为它是随机启动的好最后一点是你不必每次需要一个随机数时初始化
new Random()
,启动一个Random对象,然后在循环内需要多次使用它或者其他您还可以为
Next()
函数提供最小值和最大值 . 喜欢计算机通过确定性过程计算的数字,根据定义,不能是随机的 .
如果你想要一个真正的随机数,随机性来自大气噪声或放射性衰变 .
您可以尝试例如RANDOM.ORG(它会降低性能)
在第二个括号中放置您想要的任何值,确保通过编写prop和double选项卡来设置名称以生成代码
您可以使用下面的随机种子值尝试:
我已经尝试了所有这些解决方案,不包括COBOL答案...大声笑
这些解决方案都不够好 . 我需要在快速的int循环中使用random,即使在非常宽的范围内,我也会获得大量的重复值 . 在解决了一段随机结果后,我决定一劳永逸地解决这个问题 .
这都是关于种子的 .
我通过解析Guid中的非数字来创建一个随机整数,然后我用它来实例化我的Random类 .
Update :播种不是't necessary if you instantiate the Random class once. So it' d最好创建一个静态类并调用一个方法 .
然后你就可以像这样使用静态类了 .
我承认我更喜欢这种方法 .
来自here的修改后的答案 .
如果您可以访问与Intel Secure Key兼容的CPU,则可以使用以下库生成实际随机数和字符串:https://github.com/JebteK/RdRand和https://www.rdrand.com/
只需从here下载最新版本,包括Jebtek.RdRand并为其添加一个using语句 . 那么,你需要做的就是:
如果您没有兼容的CPU来执行代码,只需使用rdrand.com上的RESTful服务即可 . 使用项目中包含的RdRandom包装程序库,您只需要执行此操作(注册时可以获得1000个免费调用):
您可以在他为伪随机数构建的MiscUtil类库中使用Jon Skeet的StaticRandom方法 .