c# - Random(staticSeed).Next() 替代方案,永远不会改变实现,并保证通过版本保持一致

标签 c# .net random

<分区>

我正在寻找类似的东西:

new Random(staticSeed).Next() 

但我确信在不同的 .NET 框架版本中实现始终保持一致。

我正在寻找的东西:

...produces a sequence of numbers that meet certain statistical requirements for randomness.

...在 System.Random 类中引用注释。

  • .NET 中是否有类似的东西,还是我必须自己动手?
  • 现在有什么具体推荐的算法吗?

它不用于安全。

最佳答案

[这是对 usr 回答的补充]

这是 XorShift RNG 的 C# 实现,移植自 this C code :

public sealed class XorShiftRng: Random
{
    public XorShiftRng(ulong seed1, ulong seed2)
    {
        if (seed1 == 0 && seed2 == 0)
            throw new ArgumentException("seed1 and seed 2 cannot both be zero.");

        s[0] = seed1;
        s[1] = seed2;
    }

    public XorShiftRng()
    {
        var bytes = Guid.NewGuid().ToByteArray();

        s[0] = BitConverter.ToUInt64(bytes, 0);
        s[1] = BitConverter.ToUInt64(bytes, 8);
    }

    public ulong NextUlong()
    {
        unchecked
        {
            ulong s0 = s[p];
            ulong s1 = s[p = (p + 1) & 15];
            s1 ^= s1 << 31;
            s[p] = s1 ^ s0 ^ (s1 >> 11) ^ (s0 >> 30);
            return s[p]*1181783497276652981;
        }
    }

    public long NextLong(long maxValue)
    {
        return (int)NextLong(0, maxValue);
    }

    public long NextLong(long minValue, long maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentOutOfRangeException(nameof(minValue), "minValue cannot exceed maxValue");

        if (minValue == maxValue)
            return minValue;

        return (int) (NextUlong() / ((double)ulong.MaxValue / (maxValue - minValue)) + minValue);
    }

    public override int Next()
    {
        return (int) NextLong(0, int.MaxValue + 1L);
    }

    public override int Next(int maxValue)
    {
        return (int) NextLong(0, maxValue + 1L);
    }

    public override int Next(int minValue, int maxValue)
    {
        return (int) NextLong(minValue, maxValue);
    }

    public override void NextBytes(byte[] buffer)
    {
        if (buffer == null)
            throw new ArgumentNullException(nameof(buffer));

        int remaining = buffer.Length;                                 

        while (remaining > 0)
        {
            var next = BitConverter.GetBytes(NextUlong());
            int n = Math.Min(next.Length, remaining);

            Array.Copy(next, 0, buffer, buffer.Length-remaining, n);
            remaining -= n;
        }
    }

    public override double NextDouble()
    {
        return NextUlong() / (ulong.MaxValue + 1.0);
    }

    readonly ulong[] s = new ulong[16];
    int p;
}

它有一个很长的周期 2^1024 − 1,并且给出了非常好的随机数。

参见 http://xorshift.di.unimi.it/了解更多详情。

[编辑] 更新类以实现 class System.Random

关于c# - Random(staticSeed).Next() 替代方案,永远不会改变实现,并保证通过版本保持一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36331391/

相关文章:

c# - XAML 中的颜色反转

c# - 通过 RunAsync 自动使 Service Fabric Reliable Dictionary 对象过期

c# - 使用 .NET 2.0 解压缩文件

c++ - 测试检查该方法返回一个数字范围

python - tf.random.categorical 给出奇怪的结果

c# - 在创建对象的线程上调用方法

c# - 正在保存 jpeg - 该进程无法访问该文件,因为它正被另一个进程使用?

c# - MultipartFormDataContent.Add String Content 正在向名称添加回车符/换行符

c# - “IServiceCollection”不包含 'AddControllers' 的定义

arrays - 尝试从正态分布的数字生成伪随机数组/矩阵时出现问题