Random(staticSeed).Next() alternative that will never change implementation and is guaranteed consistent through versions [closed]

时光总嘲笑我的痴心妄想 提交于 2020-01-03 19:30:51

问题


I'm looking for something similar like:

new Random(staticSeed).Next() 

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

I'm specifically looking for something that:

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

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

  • Is there something like that in .NET or do I have to roll my own?
  • is there any specific recommended algorithm nowadays?

It's not used for security.


回答1:


[This is an addendum to usr's answer]

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

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

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

[EDIT] Updated class to implement class System.Random




回答2:


There is nothing in .NET like that. You probably should copy the code for a RNG from the web. I recommend using the Xor-Shift algorithm. It has very high quality, is super fast and easy to implement (5 lines I think).

Subjective note: It should have been the algorithm that the framework uses. The existing algorithm appears to be quite inferior.




回答3:


A built in way to get a seeded random sequence without rolling your own implementation of a known algorithm is use the Rfc2898DeriveBytes class. Pass in your seed as the password, use some fixed or recorded salt, and pass in 1 for iterations because you are not needing the security of multiple iterations.

This will give you a unlimited number of bytes from the GetBytes(int) call which will return the same sequence every single time for the same initial password, salt, and itterations values and will not change across .NET versions.



来源:https://stackoverflow.com/questions/36331391/randomstaticseed-next-alternative-that-will-never-change-implementation-and

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!