Your basic ITPro blog... What's going on at work, what I'm interested in.

Tuesday, October 28, 2008

Randomness... Is it possible?

I was looking at creating randomness again and came across: RNGCryptoServiceProvider

Specifically, System.Security.Cryptography.RNGCryptoServiceProvider

Most of what I read said that this is the best way to generate random values.

From what I can tell, it is designed to generate a random byte. So, it will fill a byte array with random values between 1 and 255. This is the behavior I saw when testing in PowerShell.

Most of the examples I found online of how to use this to generate a random selection out of an array of options is to do something like:

----------------------------------------------------

# Create character array
$chars = "qwertyuiopasdfghjklzxcvbnm1234567890"

# Create a byte array with one place in it
$byte = New-Object System.Byte[] 1

# Create random number generator
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider

# Fill our byte array with a random value (between 1 and 255), giving us a single random byte value
$rng.GetBytes($byte)

# Get and integer of this value
$rnd = $byte[0] -as [int]

# Generate an integer to be used as an index value in our character array
$int = ($rnd % $($chars.Length))

# Get your random character
$chars[$int]

----------------------------------------------------

While this works fine, I got to wondering if this method will favor some characters in our character array over others. For example, look at this output. I am executing the command "1..255 | % {$_ % $chars.Length} | group" which...

- counts from 1 to 255, sending each number down the pipeline
- for each number, it calcs <number> MODULO <CharArrayLength>
- it then groups my results

*************

§ Derek-D620 {C:\s\u} 1..255 | % {$_ % $chars.Length} | group

Count Name                      Group
----- ----                      -----
    8 1                         {1, 1, 1, 1...}
    8 2                         {2, 2, 2, 2...}
    8 3                         {3, 3, 3, 3...}
    7 4                         {4, 4, 4, 4...}
    7 5                         {5, 5, 5, 5...}
    7 6                         {6, 6, 6, 6...}
    7 7                         {7, 7, 7, 7...}
    7 8                         {8, 8, 8, 8...}
    7 9                         {9, 9, 9, 9...}
    7 10                        {10, 10, 10, 10...}
    7 11                        {11, 11, 11, 11...}
    7 12                        {12, 12, 12, 12...}
    7 13                        {13, 13, 13, 13...}
    7 14                        {14, 14, 14, 14...}
    7 15                        {15, 15, 15, 15...}
    7 16                        {16, 16, 16, 16...}
    7 17                        {17, 17, 17, 17...}
    7 18                        {18, 18, 18, 18...}
    7 19                        {19, 19, 19, 19...}
    7 20                        {20, 20, 20, 20...}
    7 21                        {21, 21, 21, 21...}
    7 22                        {22, 22, 22, 22...}
    7 23                        {23, 23, 23, 23...}
    7 24                        {24, 24, 24, 24...}
    7 25                        {25, 25, 25, 25...}
    7 26                        {26, 26, 26, 26...}
    7 27                        {27, 27, 27, 27...}
    7 28                        {28, 28, 28, 28...}
    7 29                        {29, 29, 29, 29...}
    7 30                        {30, 30, 30, 30...}
    7 31                        {31, 31, 31, 31...}
    7 32                        {32, 32, 32, 32...}
    7 33                        {33, 33, 33, 33...}
    7 34                        {34, 34, 34, 34...}
    7 35                        {35, 35, 35, 35...}
    7 0                         {0, 0, 0, 0...}

*****************

As you can see, some results come up more than others. Specifically (in this case) 1, 2, and 3 will show up more often than the rest of the results. So, looking at my CharArray, the letters w, e, and r will show up more often in my result sets. I am thinking that, to create an environment that does not favor any particular subset of our character array, I need my 'byte' value to be evenly divisible by my charArray length. So, rather than using a max possible value of 255, my max possible value needs to be the largest value where "maxValue MODULO charArrayLength = 0"

Ugh!

And, this doesn’t take into account the possibility that my max value could be larger than 255, in which case this formula just spits out 255.

Ugh! Ugh!

No comments:

Additional Info

My photo
email: support (AT) mangrumtech (DOT) com
mobile: 480-270-4332