How to Generate a Random Sequence with LINQ

Wyktor Zychla has an interesting post about generating random sequences using LINQ and Random. His goal was to simplify the process down to one line of code, and he achieves his goal quite well. The problem I noticed with his goal is his use of the Random class to generate random numbers. If you recall from a previous post of mine (How to Randomly Reorder a List With LINQ), the problem with Random is that it is really isn't  – random that is.

Also, if you look at Wyktor's use of Random, you'll see he isn't creating a new seed. Since the code operates rather quickly, it is very likely that Random.Next is actually repeating itself (returning the same result), since when no seed is supplied, Random uses the current time as a seed. Wyktor's solution was to use

n*n* new Random().Next()

While the results may appear  random, they are simply expontential results.

Wyktor created a function to map out the random sequence, to give a visual view of the random data generated:

static void RandomSequenceGeneratorTest( IEnumerable<int> Sequence )
{
    int Max = Sequence.Max();
 

    /* create image */
    using ( Bitmap bitmap = new Bitmap( Max, Max ) )
    using ( Graphics graphics = Graphics.FromImage( bitmap ) )
    {
        graphics.Clear( Color.Black );
 
        int prev = Sequence.First();
        foreach ( var current in Sequence.Skip(1) )
        {
            graphics.DrawRectangle(
                Pens.White,
                new Rectangle(
                    /* draw a point
                       using current and previous values
                       as coordinates
                    */
                    new Point( prev, current ),
                    new Size( 1, 1 ) ) );
 
            prev = current;
        }
 
        bitmap.Save( "test.png", ImageFormat.Png );
    }
}

You can see fromWyktor's final solution, that the results do appear random, but again, they are exponential. Thus, using our rules from the previous post, this would fail to prevent a cracker from determining the next value in the sequence.

Wyktor's Final Solution

var sequence = Enumerable.Range( 1, 500 ).OrderBy( n => n * n * ( new Random() ).Next() );
RandomSequenceGeneratorTest( sequence );

 

 

wyktor How to Generate a Random Sequence with LINQ

I propose an improved solution which uses a GUID to generate a random sequence. Remeber that a GUID is a hexadecimal number which is unique per machine (eg, no two computers will produce the same GUID). It is theoretically possible for two machines to produce the same GUID, but the odds are so astronomically high that it is almost impossible.

Generate a Random Sequence with LINQ and GUID

var sequence = Enumerable.Range(1, 500).OrderBy(n => Guid.NewGuid());

 

GUID How to Generate a Random Sequence with LINQ

You can see from the GUID results that the sequence is truly random and unique.

 

GD Star Rating
loading...
GD Star Rating
loading...
  • Share/Bookmark

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Leave a Reply