写在前面
由于C#中生成随机数使用的算法是线性同余法,意味着得出的是伪随机数,直接调用Random类来生成,出现重复数值的概率非常高。
Random random = new Random();
var rnd = random.Next();
这个结果肯定是不满足要求的,可以采用系统启动时间戳来做随机数种子,同时结合线程变量来生成随机数,这样得到的随机数更为可靠。
代码实现
public static class RandomProvider
{
private static int _seed = Environment.TickCount;
private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
new Random(Interlocked.Increment(ref _seed))
);
public static Random GetThreadRandom()
{
_seed = Environment.TickCount;
return randomWrapper.Value;
}
public static int GetRandomValue(int min, int max)
{
var random = GetThreadRandom();
return random.Next(min, max + 1);
}
public static float GetRandomValue(float min, float max)
{
var random = GetThreadRandom();
var minFloat = (int)(min * 1000);
var maxFloat = (int)(max * 1000);
return random.Next(minFloat, maxFloat + 1) / 1000;
}
public static int Range(int min, int max)
{
return GetRandomValue(min, max);
}
public static float Range(float min, float max)
{
return GetRandomValue(min, max);
}
public static string GetRandomName(int length)
{
var wArr = new string[]
{
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
};
var nArr = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
var sList = new List<string>();
for (int j = 0; j < length; j++)
{
var str = string.Empty;
if (j > 0 && j < length - 1)
{
var n = GetRandomValue(0, 100);
if (n < 20)
{
var x = GetRandomValue(0, 9);
str = nArr[x];
sList.Add(str);
continue;
}
}
var i = GetRandomValue(0, 51);
str = wArr[i];
sList.Add(str);
}
return string.Join(string.Empty, sList);
}
}
总结
为了生成更加可靠的随机数,还有很多其他的方式,比如微软在System.Security.Cryptography命名空间下,就提供一个名为RNGCryptoServiceProvider的类,它采用系统当前的硬件信息、进程信息、线程信息、系统启动时间和当前精确时间作为填充因子,通过更好的算法生成高质量的随机数。在Windows Api中也提供了一个非托管的随机数生成函数CryptGenRandom,由于是C++实现的,在C#中调用需要另外加一层封装;在大部分情况下本文所提供的随机数生成类产生的随机数质量已经可以满足需求了。
文章介绍了如何在C#中通过使用系统启动时间戳和线程局部变量改进Random类生成随机数的质量,以降低重复值概率,并提及了System.Security.Cryptography命名空间和WindowsAPI中的高级随机数生成选项。
1584

被折叠的 条评论
为什么被折叠?



