拥有这个(简化的)C#类:
public static class RandomValue
{
private static readonly Random s_random = new Random();
public static int GetRandomValue()
{
lock (s_random)
{
return s_random.Next();
}
}
}
通过查看此方法生成的值,是否可以预测GetRandomValue()
的下一个值?
假设(为了问题):
GetRandomValue()
。我问,因为我已经看到一些代码使用类似的方法来生成某种访问令牌。这段代码不是我编写的,我可能会使用.NET的加密随机类之一。我只是好奇这是否仍然足够安全。
答案 0 :(得分:4)
根据kennytm的评论,我创建了一个关于如何“打破”Random
的概念证明。边缘可能有点粗糙,但它表明您只需要55个值来预测下一个(以及之后的每个值)。
以下代码首先从单个Random
实例读取55个值,然后预测接下来的10个值:
public class Program
{
static void Main(string[] args)
{
const int INTERNAL_ARRAY_SIZE = 56;
const int INEXTP_START = 21;
var internalArray = new int[INTERNAL_ARRAY_SIZE];
var random = new Random();
// Read 56 values.
for (int x = 0; x < INTERNAL_ARRAY_SIZE - 1; x++)
{
internalArray[x + 1] = random.Next();
}
int inext = INTERNAL_ARRAY_SIZE - 1;
int inextp = INEXTP_START;
// Predict the next 10 values.
for (int x = 0; x < 10; x++)
{
int predictedRandomValue = PredictNextRandomValue(internalArray, ref inext, ref inextp);
int officialRandomValue = random.Next();
if (officialRandomValue == predictedRandomValue)
{
Console.WriteLine("Yes, they're the same.");
}
else
{
Console.WriteLine("No, they're different.");
}
}
}
private static int PredictNextRandomValue(int[] seedArray, ref int inext, ref int inextp)
{
const int MBIG = int.MaxValue;
int retVal;
int locINext = inext;
int locINextp = inextp;
if (++locINext >= 56) locINext = 1;
if (++locINextp >= 56) locINextp = 1;
retVal = seedArray[locINext] - seedArray[locINextp];
if (retVal == MBIG) retVal--;
if (retVal < 0) retVal += MBIG;
seedArray[locINext] = retVal;
inext = locINext;
inextp = locINextp;
return retVal;
}
}