本文介绍了Random(staticSeed).Next()替代方案,它永远不会改变实现,并且在各个版本中保证一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找类似的东西:

I'm looking for something similar like:

new Random(staticSeed).Next() 

但是我确信通过不同的.NET Framework版本,实现将始终保持一致.

but where I'm assured that the implementation will always be consistent through different .NET framework versions.

我正在寻找一些东西:

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

...to quote the comment at the System.Random class.

  • .NET中是否有类似的东西,还是我必须自己动手?
  • 当今是否有特定的推荐算法?

它不是用于安全性.

推荐答案

[这是usr答案的附录]

[This is an addendum to usr's answer]

这是XorShift RNG的C#实现,从此C代码移植:

Here's a C# implementation of an XorShift RNG, ported from 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,并且给出了很好的随机数.

It has a long period of 2^1024 − 1, and gives very good random numbers.

有关更多详细信息,请参见 http://xorshift.di.unimi.it/.

See http://xorshift.di.unimi.it/ for more details.

更新了类,以实现 System.Random

这篇关于Random(staticSeed).Next()替代方案,它永远不会改变实现,并且在各个版本中保证一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 23:33