using System.Numerics; namespace WebmrAPI.Utils { public class BaseRandom { private readonly static Random _random = new Random(); private static readonly BaseRandom _self = new BaseRandom(); protected Random? _pRandom = null; private Random Rand { get => _pRandom == null ? _random : _pRandom; } public static byte[] NextGenerate(byte[] data) { return _self.Generate(data); } public static T NextGenerate(T min, T max) where T : struct, INumber { return _self.Generate(min, max); } public static T NextSpread(T value, T offset) where T : struct, INumber { return _self.Spread(value, offset); } public byte[] Generate(byte[] data) { Rand.NextBytes(data); return data; } public double Generate(double min, double max) { if (min > max) { throw new ArgumentOutOfRangeException(nameof(min), "minValue cannot be greater than maxValue."); } return min + (max - min) * Rand.NextDouble(); } public long Generate(long min, long max) { return Rand.NextInt64(min, max + 1); } public ulong Generate(ulong min, ulong max) { ulong res; long lmin = (long)min; long lmax = (long)max; if (lmin > lmax) res = (ulong)Rand.NextInt64(lmax, lmin + 1); else res = (ulong)Rand.NextInt64(lmin, lmax + 1); return UInt64.Clamp(res, min, max); } public uint Generate(uint min, uint max) { return (uint)Generate((long)min, (long)max); } public T Generate(T min, T max) where T : struct, INumber { var min32 = Int32.CreateChecked(min); var max32 = Int32.CreateChecked(max); return T.CreateChecked(Rand.Next(min32, max32)); } public T Spread(T value, T offset) where T : struct, INumber { T min, max, cur; cur = T.CreateChecked(Math.Abs(Double.CreateChecked(offset))); min = value - cur; max = value + cur; if (min > max) { var tmp = min; min = max; max = tmp; } value = Generate(min, max); return value; } public BaseRandom() { } public BaseRandom(int seed) { _pRandom = new Random(seed); } } }