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; } }