public static System.Guid GetGuid(IRandom rand)
        {
            byte[] buffer = new byte[16];
            rand.NextBytes(buffer);

            return new System.Guid(buffer);
        }
        public static System.Byte[] GetBinary(IRandom rand, int minLength, int maxLength)
        {
            int length = rand.Next(minLength, maxLength);
            byte[] result = new byte[length];
            rand.NextBytes(result);

            return result;
        }
        public static System.Double GetDouble(	IRandom rand, 
												System.Double min = System.Double.MinValue, 
												System.Double max = System.Double.MaxValue)
        {
            byte[] buffer = new byte[8];
            rand.NextBytes(buffer);

            System.Double result = System.BitConverter.ToDouble(buffer, 0);

            if(result < min)
                return min;
            else if(result >= max)
                return max - 1;
            else
                return result;
        }
        private static double MeasureChiSquared(IRandom random, int rounds)
        {
            var counts = new int[256];

            var bs = new byte[256];
            for (var i = 0; i < rounds; ++i)
            {
                random.NextBytes(bs);

                for (var b = 0; b < 256; ++b)
                {
                    ++counts[bs[b]];
                }
            }

            var mask = SecureRandom.GetSeed(1)[0];
            for (var i = 0; i < rounds; ++i)
            {
                random.NextBytes(bs);

                for (var b = 0; b < 256; ++b)
                {
                    ++counts[bs[b] ^ mask];
                }

                ++mask;
            }

            var shift = SecureRandom.GetSeed(1)[0];
            for (var i = 0; i < rounds; ++i)
            {
                random.NextBytes(bs);

                for (var b = 0; b < 256; ++b)
                {
                    ++counts[(byte)(bs[b] + shift)];
                }

                ++shift;
            }

            var total = 3 * rounds;

            double chi2 = 0;
            for (var k = 0; k < counts.Length; ++k)
            {
                var diff = ((double)counts[k]) - total;
                var diff2 = diff * diff;

                chi2 += diff2;
            }

            chi2 /= total;

            return chi2;
        }
        public BigInteger(
            int bitLength,
            int certainty,
            IRandom random)
        {
            if (bitLength < 2)
                throw new ArithmeticException("bitLength < 2");

            this.SignValue = 1;
            this.nBitLength = bitLength;

            if (bitLength == 2)
            {
                this.Magnitude = random.Next(2) == 0
                                     ? Two.Magnitude
                                     : Three.Magnitude;
                return;
            }

            int nBytes = GetByteLength(bitLength);
            var b = new byte[nBytes];

            int xBits = BitsPerByte*nBytes - bitLength;
            byte mask = rndMask[xBits];

            for (;;)
            {
                random.NextBytes(b);

                // strip off any excess bits in the MSB
                b[0] &= mask;

                // ensure the leading bit is 1 (to meet the strength requirement)
                b[0] |= (byte) (1 << (7 - xBits));

                // ensure the trailing bit is 1 (i.e. must be odd)
                b[nBytes - 1] |= 1;

                this.Magnitude = MakeMagnitude(b, 0, b.Length);
                this.nBits = -1;
                this.mQuote = -1L;

                if (certainty < 1)
                    break;

                if (CheckProbablePrime(certainty, random))
                    break;

                if (bitLength > 32)
                {
                    for (int rep = 0; rep < 10000; ++rep)
                    {
                        int n = 33 + random.Next(bitLength - 2);
                        this.Magnitude[this.Magnitude.Length - (n >> 5)] ^= (1 << (n & 31));
                        this.Magnitude[this.Magnitude.Length - 1] ^= ((random.Next() + 1) << 1);
                        this.mQuote = -1L;

                        if (CheckProbablePrime(certainty, random))
                            return;
                    }
                }
            }
        }
        public BigInteger(int sizeInBits, IRandom random)
        {
            if (sizeInBits < 0)
                throw new ArgumentException("sizeInBits must be non-negative");

            this.nBits = -1;
            this.nBitLength = -1;

            if (sizeInBits == 0)
            {
                //				this.sign = 0;
                this.Magnitude = ZeroMagnitude;
                return;
            }

            int nBytes = GetByteLength(sizeInBits);
            var b = new byte[nBytes];
            random.NextBytes(b);

            // strip off any excess bits in the MSB
            b[0] &= rndMask[BitsPerByte*nBytes - sizeInBits];

            this.Magnitude = MakeMagnitude(b, 0, b.Length);
            this.SignValue = this.Magnitude.Length < 1 ? 0 : 1;
        }
        public static System.Int64 GetInt64(IRandom rand, 
											System.Int64 min = System.Int64.MinValue,
											System.Int64 max = System.Int64.MaxValue)
        {
            byte[] buffer = new byte[8];
            rand.NextBytes(buffer);

            System.Int64 result = System.BitConverter.ToInt64(buffer, 0);

            if(result < min)
                return min;
            else if(result >= max)
                return max - 1;
            else
                return result;
        }