64 bit Strong Random function

  • Thread starter Thread starter Stu Banter
  • Start date Start date
S

Stu Banter

Hi,

On a previous question someone recommended using the
System.Security.Cryptography to fill an array with strong random bytes.

It works but I can't specify the max value of course.. I solved it by
subsequently removing all 'higher than max' values, but this is not
efficient, nor fast.

Anyone who can point me to a C#-usable Random Number Generator with at least
52 bits? And more random than the default System.Random (fails several of
the online tests).

I need it for Monte Carlo type of simulations with a deck of cards (hence
the 52 bits).

Thanks!
 
Hello

You can still use cryptography
Instead of removing numbers higher than max, you can do the following:
randomNumber = randomNumber % maxValue; //min value is zero

if you have a minimum value
randomNumber = randomNumber % (maxValue - minValue) + minValue;

the first case is the same as second case with minValue = 0;
the generated number less then maxValue and greater than or equal minValue

minValue <= randomNumber < maxValue


Best regards
Sherif
 
Hi Stu,

Out of interest, how are you using Cryptography to get your random
numbers? And what are you then doing with them?

The reason I ask is that you mention bits - 52 to be exact - so I'm
wondering whether this might of any use:

byte aBytes [8];
Security.Cryptography.RNGCryptoServiceProvider oRndGen;
oRndGen = new Security.Cryptography.RNGCryptoServiceProvider();
oRndGen.GetBytes (aBytes);
BitArray Bits = new BitArray (aBytes);
Bits.Length = 52;

Regards,
Fergus
 
Sherif ElMetainy said:
Hello

You can still use cryptography
Instead of removing numbers higher than max, you can do the following:
randomNumber = randomNumber % maxValue; //min value is zero

If you mean I should do that to the values once they are in the ByteArray,
it will not provide equal distribution, since 52 only fits 4 times in 255,
the highest numbers from 48 / 52 will appear 20% less than the others...
(255-208=47) No I am not smart, tried it and cracked my brain for a day on
that....

Anyway, thanks for your time and reply, and perhaps you meant something else
??? In that case I missed something the .NET ide....

Cheers
Stu
 
Fergus Cooney said:
Hi Stu,

Out of interest, how are you using Cryptography to get your random
numbers? And what are you then doing with them?

I started out using the regular System.Random like below:

class Deck
{
private int [] deck = new int [52];
private Random rnd = new Random ();

public Deck ()
{
for (int i = 0; i < 52; i++)
{ deck = i; } // I calculate Suit and Rank elsewhere using
div and mod 13
}

public void shuffle ()
{
int x = 0;
for (int i = 0; i < 52; i++)
{
x = rnd.Next (52-i) + i + 1; // pick a random card from the
cards NOT shuffled yet
int hvar = deck ;
deck = deck [x];
deck [x] = hvar;
}
}
// and the rest of the class definitiion, irrelevant here....
}

I found out 32 bits random will never be able to produce all possible 52!
deck shufflings. Hence I looked further for a better randomizer able to
produce that many diiferent values at least... (Besides I read articles
stating the default Random function is not very random indeed and fails
several random tests (google!))

I then got pointed to the Cryptography one, which is supposedly more random,
and perhaps has a bigger range of random values it can produce... Not sure
though, haven't found much documentation on the inner workings of
Cryptography's random.
The reason I ask is that you mention bits - 52 to be exact - so I'm
wondering whether this might of any use:

byte aBytes [8];
Security.Cryptography.RNGCryptoServiceProvider oRndGen;
oRndGen = new Security.Cryptography.RNGCryptoServiceProvider();
oRndGen.GetBytes (aBytes);
BitArray Bits = new BitArray (aBytes);
Bits.Length = 52;

This looks interesting, I am not that great in C# and the tricks you pull
here if that is doing what I would like it to do.... But I'll study it in
more detail, haven't seen the construction before. I tried the trick Sherif
answered with, and found out (read reply for details) it didn't produce
desirable results...

FYI, all this started when I read an article at www.paradisepoker.com about
the random functions used for the online poker games, and another article
about how the first generation of these online games were quite easily
cracked, and had faulty shuffling routines to boot (they included ALL 52
cards in each shuffle action. This leads to some deck shufflings appearing
more often than others. Lost the link unfortunately.Maybe Google ?
Regards,
Fergus
Fergus, you too, thanks a bunch for loking into it. I may be completely on a
wrong path here, so feel free to get me back on track! I owe you one!

Best!

Stu
 
I forgot to mention (you may have grasped already though) It is a DECK of
cards we're talking about.. Building a poker simulator /online play
assistant
 
Hello

Actually I meant you apply the % operator to the random 64-bit number with
max value 2^52.

long maxValue = 1L << 52;
long randomNumber = BitConverter.ToInt64(byteArray);
randomNumber = randomNumber % (maxValue - minValue) + minValue;


The distribution should be very good in this case.

Best regards
Sherif
 
Thanks! That would definitely be a good option I think. Nice solution too!

Regards,
Stu
 
Back
Top