winmr-api/Utils/BaseRandom.cs
2026-01-08 21:35:06 +03:00

95 lines
2.6 KiB
C#

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>(T min, T max)
where T : struct, INumber<T>
{
return _self.Generate(min, max);
}
public static T NextSpread<T>(T value, T offset)
where T : struct, INumber<T>
{
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>(T min, T max) where T : struct, INumber<T>
{
var min32 = Int32.CreateChecked(min);
var max32 = Int32.CreateChecked(max);
return T.CreateChecked(Rand.Next(min32, max32));
}
public T Spread<T>(T value, T offset)
where T : struct, INumber<T>
{
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);
}
}
}