Random64d.cs

Posted on June 24, 2020June 25, 2020Tags , , ,   Leave a comment on Random64d.cs

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

JitterEx.cs

Posted on June 4, 2020June 28, 2020Tags , , ,   Leave a comment on JitterEx.cs
using System;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Threading;
[Serializable]
public class JitterEx
{
    private const    int                      DesaturationLoopLimit = 500;
    private const    int                      UpperCpuLoadLimit     = 90;
    private const    int                      LowerCpuLoadLimit     = 10;
    private static   bool                     _scaleSet;
    private readonly int                      _bufferSize;
    private readonly object                   _lock = new object();
    private readonly RNGCryptoServiceProvider _prng;
    private          byte[]                   _rngCache;
    private          int                      _tscLoopLimitCpu  = 20;
    private          int                      _tscSampleSizeRam = 10;
    public JitterEx(int buffersize)
    {
        if (buffersize < 256)
            throw new ArgumentException("Buffer Size cannot be less than 256 bytes.");
        _bufferSize = buffersize;
        _rngCache   = new byte[_bufferSize];
        _prng       = new RNGCryptoServiceProvider();
        SetScale();
    }
    private float GetCpuSpeed()
    {
        void Loop()
        {
            var i = 0;
            while (true)
                i = i + 1 - 1;
        }
        var cpuCounter = new PerformanceCounter("Processor Information", "% Processor Performance", "_Total");
        var cpuValue   = cpuCounter.NextValue();
        var loop       = new Thread(() => Loop()) {Priority = ThreadPriority.Highest};
        var Speed      = 0f;
        lock (_lock)
        {
            loop.Start();
            Thread.Sleep(60);
            cpuValue = cpuCounter.NextValue();
            loop.Abort();
        }
        foreach (ManagementObject obj in new ManagementObjectSearcher("SELECT *, Name FROM Win32_Processor").Get())
            Speed = Convert.ToSingle(obj["MaxClockSpeed"]) / 1000 * cpuValue / 100;
        return Speed;
    }
    /// <summary>
    ///     This is a fairly arbitrary value which is based on the CPU speed
    /// </summary>
    private void SetScale()
    {
        if (_scaleSet)
            return;
        _scaleSet = true;
        const float baseFreq = 4.277f;
        var         thisFreq = GetCpuSpeed();
        var         rat      = baseFreq / thisFreq;
        _tscLoopLimitCpu  = (int) Math.Ceiling(_tscLoopLimitCpu  * rat);
        _tscSampleSizeRam = (int) Math.Ceiling(_tscSampleSizeRam * rat);
    }
    private void LoadBlock()
    {
        var DesaturationLoops = 0;
        var dump              = CpuTotalPc.CPULoad;
        do
        {
            Thread.Sleep(0);
            DesaturationLoops++;
        } while (DesaturationLoops < DesaturationLoopLimit && ((int) CpuTotalPc.CPULoad > UpperCpuLoadLimit || (int) CpuTotalPc.CPULoad < LowerCpuLoadLimit));
    }
    [MethodImpl(MethodImplOptions.NoInlining)]
    private byte[] GetBufferCpu()
    {
        var jitterBuffer = new byte[_bufferSize];
        var loop         = 0;
        while (true)
        {
            var ptr = 0;
            var x   = 0;
            LoadBlock();
            lock (_lock)
            {
                var start = Rdtsc.TimestampP();
                do
                {
                    for (var i = 0; i < _tscLoopLimitCpu; i++)
                        x = x + 1 - 1;
                    var stop = Rdtsc.TimestampP();
                    Buffer.BlockCopy((100000.0 / ((stop - start) * 100000.0)).GetBytes(), 0, jitterBuffer, ptr, 4);
                    start =  stop;
                    ptr   += 4;
                } while (ptr < _bufferSize);
                return jitterBuffer;
            }
        }
        return jitterBuffer;
    }
    [MethodImpl(MethodImplOptions.NoInlining)]
    private unsafe byte[] GetBufferRam()
    {
        LoadBlock();
        var jitterBuffer = new byte[_bufferSize];
        lock (_lock)
        {
            if (_rngCache.Length != _bufferSize)
                _rngCache = new byte[_bufferSize];
            _prng.GetBytes(_rngCache);
            var  ptr = 0;
            byte tempByte;
            var  start = Rdtsc.TimestampP();
            while (true)
            {
                fixed (byte* p1 = _rngCache)
                {
                    var x1 = p1;
                    for (var j = 0; j < _tscSampleSizeRam; ++j, ++x1)
                        tempByte = *x1;
                }
                var stop = Rdtsc.TimestampP();
                Buffer.BlockCopy((100000.0 / ((stop - start) * 100000.0)).GetBytes(), 0, jitterBuffer, ptr, 4);
                start =  stop;
                ptr   += 4;
                if (ptr < _bufferSize)
                {
                    if (_rngCache.Length != _bufferSize)
                        _rngCache = new byte[_bufferSize];
                    _prng.GetBytes(_rngCache);
                }
                else
                {
                    break;
                }
            }
        }
        return jitterBuffer;
    }
    private double Entropy(byte[] ba)
    {
        var map = new int[256];
        foreach (var i in ba)
            map[i]++;
        var lot = Math.Log(2);
        return map.Where(item => item > 0).Select(item => item / (double) ba.Length).Aggregate(0.0, (current, frequency) => current - frequency * (Math.Log(frequency) / lot));
    }
    public byte[] GetBuffer()
    {
        var firstBuffer  = GetBufferCpu();
        var secondBuffer = GetBufferRam();
        var finalBuffer  = new byte[_bufferSize];
        for (var j = 0; j < _bufferSize; ++j)
            finalBuffer[j] = (byte) (firstBuffer[j] ^ secondBuffer[j]);
        return finalBuffer;
    }
}