Can Random.Next() be predicted from its outputs

前端 未结 1 1577
情话喂你
情话喂你 2021-01-06 19:31

Having this (simplified) C# class:

public static class RandomValue
{
    private static readonly Random s_random = new Random();

    public static int GetRa         


        
相关标签:
1条回答
  • 2021-01-06 19:32

    Based on kennytm's comment I created a proof of concept on how to to "break" Random. It may be a little rough around the edges but it shows that you only need 55 values to predict the next one (and every value after that).

    The following code first reads 55 values from a single Random instance and then predicts the next 10 values:

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题