在C#中随机化通用列表顺序的最佳方法是什么?我在一个列表中有一组有限的75个数字,我想为其分配一个随机顺序,以便为抽奖类型的应用程序绘制它们.
为什么181783497276652981和8682522807148012在选择Random.java?
这是Java SE JDK 1.7的相关源代码:
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current …Run Code Online (Sandbox Code Playgroud) 为什么有人会使用System.Random中的"标准"随机数生成器,而不是总是使用System.Security.Cryptography.RandomNumberGenerator(或其子类,因为RandomNumberGenerator是抽象的)的加密安全随机数生成器?
Nate Lawson 在13:11分钟的Google Tech Talk演讲中告诉我们" Crypto Strikes Back ",不要使用Python,Java和C#中的"标准"随机数生成器,而是使用加密安全版本.
我知道两个版本的随机数生成器之间的区别(参见问题101337).
但是,有什么理由不总是使用安全随机数发生器?为什么要使用System.Random?性能或许?
什么是使用的利弊System.Security.Cryptography.RNGCryptoServiceProviderVS System.Random.我知道这RNGCryptoServiceProvider是"更随机",即黑客可预测性更低.任何其他利弊?
更新:
根据回复,以下是目前使用的利弊RNGCryptoServiceProvider:
RNGCryptoServiceProvider 是一个更强大的加密随机数,这意味着它更适合确定加密密钥等.Random更快,因为它是一个更简单的计算; 当在模拟或长时间计算中使用加密随机性不重要时,应该使用它.注意:有关模拟的详细信息,请参阅Kevin的答案 - Random不一定是随机的,您可能希望使用不同的非加密PRNG.有人可以验证这种方法.我需要在两个长度范围内的长型号码.我使用返回int的.NET Random.Next(min,max)函数.如果我将long除以2,生成随机数并最终再乘以2,我的推理是否正确?或者我太热情......我明白我的随机解决方案会减少但是还有其他错误导致没有这样的随机数.
long min = st.MinimumTime.Ticks; //long is Signed 64-bit integer
long max = st.MaximumTime.Ticks;
int minInt = (int) (min / 2); //int is Signed 64-bit integer
int maxInt = (int) (max / 2); //int is Signed 64-bit integer
Random random = new Random();
int randomInt = random.Next(minInt, maxInt);
long randomLong = (randomInt * 2);
Run Code Online (Sandbox Code Playgroud) 好.以下是我所知道的不起作用:
int Rand()
{
//will return the same number over and over again
return new Random().Next();
}
static Random rnd=new Random();
int Rand()
{
//if used like this from multiple threads, rnd will dissintegrate
//over time and always return 0
return rnd.Next();
}
Run Code Online (Sandbox Code Playgroud)
这将正常工作,但如果由多个线程使用,CPU使用率上升,我不想要,我认为没有必要:
int Rand()
{
lock(rnd)
{
return rnd.Next();
}
}
Run Code Online (Sandbox Code Playgroud)
那么,c#是否有一个线程安全的Random类,或者更好的方法来使用它?
我想在linq中获取一个随机对象.我就是这样做的.
//get all the answers
var Answers = q.Skip(1).Take(int.MaxValue);
//get the random number by the number of answers
int intRandomAnswer = r.Next(1, Answers.Count());
int count = 0;
//locate the answer
foreach(var Answer in Answers)
{
if (count == intRandomAnswer)
{
SelectedPost = Answer;
break;
}
count++;
}
Run Code Online (Sandbox Code Playgroud)
这是最好的方法吗?
考虑以下程序:
public class Program
{
private static Random _rnd = new Random();
private static readonly int ITERATIONS = 5000000;
private static readonly int RANDOM_MAX = 101;
public static void Main(string[] args)
{
ConcurrentDictionary<int,int> dic = new ConcurrentDictionary<int,int>();
Parallel.For(0, ITERATIONS, _ => dic.AddOrUpdate(_rnd.Next(1, RANDOM_MAX), 1, (k, v) => v + 1));
foreach(var kv in dic)
Console.WriteLine("{0} -> {1:0.00}%", kv.Key, ((double)kv.Value / ITERATIONS) * 100);
}
}
Run Code Online (Sandbox Code Playgroud)
这将打印以下输出:
(注意每次执行时输出会有所不同)
> 1 -> 97,38%
> 2 -> 0,03%
> 3 -> …Run Code Online (Sandbox Code Playgroud) 如果我运行此测试:
var r = new Random();
var ints = new int[13];
Parallel.For(0, 2000000, i => {
var result = r.Next(1, 7) + r.Next(1, 7);
ints[result] += 1;
});
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
2: 92,14445
3: 0,41765
4: 0,62245
5: 0,82525
6: 1,04035
7: 1,25215
8: 1,0531
9: 0,8341
10: 0,6334
11: 0,4192
12: 0,2109
Run Code Online (Sandbox Code Playgroud)
当我使用常规For:
for (int i = 0; i < 2000000; i++) {
var result = r.Next(1, 7) + r.Next(1, 7);
ints[result] += 1;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
2: 2,7797
3: 5,58645
4: …Run Code Online (Sandbox Code Playgroud) c# ×7
random ×7
.net ×5
c#-4.0 ×2
.net-4.0 ×1
cryptography ×1
generic-list ×1
guid ×1
java ×1
linq ×1