64 Bit Version of Random
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
[Serializable]
public class Random64d : RandomNumberGenerator
{
private const double DBi = 1.0 / 9223372036854775807;
private const double DBui = 1.0 / ulong.MaxValue;
private readonly Random _r1;
private readonly Random _r2;
[NonSerialized] private readonly RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
private RNumber _rNumber;
public Random64d() : this(((long) (uint) Environment.TickCount << 32) | (uint) Environment.TickCount)
{
}
public Random64d(long Seed)
{
var Seed0 = (int) (((Seed ^ 0x86B28CAB) << 16) & 0x7fffffff);
var Seed1 = (int) (Seed & 0x7fffffff);
_r1 = new Random(Seed0);
_r2 = new Random(Seed1);
}
public long InternalSample()
{
_rNumber.n1 = _r1.Next();
_rNumber.n2 = _r2.Next();
return _rNumber.total;
}
private double GetSampleForLargeRange()
{
var value = InternalSample();
if (InternalSample() % 2 == 0)
value = -value;
return (value + 4611686018427387903.0) / 9223372036854775807.0;
}
private double Sample()
{
return InternalSample() * DBi;
}
public long Next()
{
return InternalSample();
}
public long Next(long minValue, long maxValue)
{
if (minValue > maxValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
var num = (ulong) maxValue - (ulong) minValue;
if (num <= long.MaxValue)
return (long) (Sample() * num) + minValue;
return (long) ((ulong) (GetSampleForLargeRange() * num) + (ulong) minValue);
}
public ulong Next(ulong minValue, ulong maxValue)
{
if (minValue > maxValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
var num = maxValue - minValue;
return (ulong) (InternalSample() * DBui * num) + minValue;
}
public long Next(long maxValue)
{
if (maxValue < 0)
throw new ArgumentException("maxValue must be greater than zero.");
return (long) (Sample() * maxValue);
}
public ulong Next(ulong maxValue)
{
return (ulong) (InternalSample() * DBui * maxValue);
}
public double NextDouble()
{
return Sample();
}
public byte[] GetNextByteArray(int size)
{
var ba = new byte[size];
_rng.GetBytes(ba);
return ba;
}
public byte[] GetNextByteArrayFn(int size)
{
var ba = new byte[size];
for (var i = 0; i < size; ++i)
ba[i] = (byte) Next(0, 256);
return ba;
}
public char[] GetNextCharArray(int size)
{
var ca = new char[size];
for (var i = 0; i < size; ++i)
ca[i] = (char)Next(32, 128);
return ca;
}
public string GetRandomString(int minLen, int maxLen)
{
if (minLen == maxLen)
return new string(GetNextCharArray(minLen));
return new string(GetNextCharArray((int) Next(minLen, maxLen)));
}
public override void GetBytes(byte[] data)
{
if (data == null)
throw new ArgumentException("The buffer cannot be null.");
_rng.GetBytes(data);
}
[StructLayout(LayoutKind.Explicit, Size = 8, Pack = 1)]
[Serializable]
public struct RNumber
{
[FieldOffset(0)] public long n1;
[FieldOffset(4)] public long n2;
[FieldOffset(0)] public long total;
}
}