我有一个方法,我用它来创建随机字符串,通过创建随机整数并将它们转换为char
public static string GenerateRandomString(int minLength, int maxLength)
{
var length = GenerateRandomNumber(minLength, maxLength);
var builder = new StringBuilder(length);
var random = new Random((int)DateTime.Now.Ticks);
for (var i = 0; i < length; i++)
{
builder.Append((char) random.Next(255));
}
return builder.ToString();
}
问题在于,当我经常调用此方法时,它会创建相同的值序列,正如文档已经说过的那样:
随机数生成从种子值开始。如果相同 种子被重复使用,生成相同的数字序列。一 产生不同序列的方法是制作种子值 时间依赖,从而与每个新系列产生不同的系列 随机实例。
正如您所看到的,我将依赖种子时间,并在每次调用方法时创建Random
的新实例。尽管如此,我的测试仍然失败。
[TestMethod]
public void GenerateRandomStringTest()
{
for (var i = 0; i < 100; i++)
{
var string1 = Utilitaries.GenerateRandomString(10, 100);
var string2 = Utilitaries.GenerateRandomString(10, 20);
if (string1.Contains(string2))
throw new InternalTestFailureException("");
}
}
如何确保独立于我调用方法的频率,序列将“始终”不同?
答案 0 :(得分:3)
您的测试失败,因为GenerateRandomString
功能过早完成DateTime.Now.Ticks
更改。在大多数系统上,它是quantized at either 10 or 15 ms,这足以让现代CPU生成100个随机字符的序列。
在测试中插入一个小延迟应解决问题:
var string1 = Utilitaries.GenerateRandomString(10, 100);
Thread.Sleep(30);
var string2 = Utilitaries.GenerateRandomString(10, 20);
答案 1 :(得分:2)
你实际上和Random
的默认构造函数一样。它正在使用Environment.TickCount
。查看this MSDN documentation中Random
构造函数的示例。它表明在不同Thread.Sleep
实例的初始化之间插入Random
将产生不同的结果。
如果您真的想获得不同的值,我建议您更改为不时间相关的种子值。
答案 2 :(得分:1)
dasblinkenlight已经说明了为什么会这样。
现在你应该这样做来克服这个问题
public static string GenerateRandomString(Random random , int minLength,
int maxLength)
{
var length = GenerateRandomNumber(random , minLength, maxLength);
var builder = new StringBuilder(length);
for (var i = 0; i < length; i++)
builder.Append((char) random.Next(255));
return builder.ToString();
}
public void GenerateRandomStringTest()
{
Random rnd = New Random();
for (var i = 0; i < 100; i++)
{
var string1 = Utilitaries.GenerateRandomString(rnd, 10, 100);
var string2 = Utilitaries.GenerateRandomString(rnd, 10, 20);
if (string1.Contains(string2))
throw new InternalTestFailureException("");
}
}