有没有办法抓住System.Random的实际状态?没有办法、实际、状态、Random

2023-09-04 00:20:07 作者:江南樱雨﹍断桥殇

我希望能够得到的实际状态或种子或其他System.Random的,所以我可以关闭一个应用程序,当用户重新启动它,它只是重播,它与存储的之一,并继续喜欢它从未关闭。

这可能吗?

使用乔恩的想法,我想出了这个测试它;

 静态无效的主要(字串[] args)
{
    VAR OBJ =新的随机();
    IFormatter格式化=新的BinaryFormatter();
    流流=新的FileStream(C:\\的test.txt,FileMode.Create,FileAccess.Write,FileShare.None);
    formatter.Serialize(流OBJ);
    stream.Close();
    为(变种I = 0; I&小于10;我+ +)
        Console.WriteLine(obj.Next()的ToString());

    Console.WriteLine();

    格式化=新的BinaryFormatter();
    流=新的FileStream(C:\\的test.txt,FileMode.Open,FileAccess.Read,FileShare.Read);
    OBJ =(随机)formatter.Deserialize(流);
    stream.Close();
    为(变种I = 0; I&小于10;我+ +)
        Console.WriteLine(obj.Next()的ToString());

    Console.Read();
}
 

解决方案

这是序列化的,所以你会发现你可以使用的BinaryFormatter 并保存字节数组...

样品code:

 使用系统;
使用System.IO;
使用System.Runtime.Serialization.Formatters.Binary;

公共类节目
{
    公共静态无效的主要(字串[] args)
    {
        随机RNG =新的随机();
        Console.WriteLine(保存前值...);
        ShowValues​​(RNG);

        BinaryFormatter的格式化=新的BinaryFormatter();
        MemoryStream的流=新的MemoryStream();
        formatter.Serialize(流,RNG);

        Console.WriteLine(保存后值...);
        ShowValues​​(RNG);

        stream.Position = 0; //倒带准备好读
        随机恢复=(随机)formatter.Deserialize(流);

        Console.WriteLine(恢复后的价值......);
        ShowValues​​(恢复);
    }

    静态无效ShowValues​​(随机RNG)
    {
        的for(int i = 0;我小于5;我++)
        {
            Console.WriteLine(rng.Next(100));
        }
    }
}
 

结果在样品运行是有希望的:

在保存前

 值...
25
73
58
6
33
保存后值...
71
7
87
3
77
恢复后的价值...
71
7
87
3
77
 
小米还是出手了,高通 不死心 也没有办法,只能被迫接受现实

诚然,我并不热衷于内置的序列化,但如果这是一个相当快速和肮脏的黑客,应该没关系......

I would like to be able to get the actual state or seed or whatever of System.Random so I can close an app and when the user restarts it, it just "reseeds" it with the stored one and continues like it was never closed.

Is it possible?

Using Jon's idea I came up with this to test it;

static void Main(string[] args)
{
    var obj = new Random();
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream("c:\\test.txt", FileMode.Create, FileAccess.Write, FileShare.None);
    formatter.Serialize(stream, obj);
    stream.Close();
    for (var i = 0; i < 10; i++)
        Console.WriteLine(obj.Next().ToString());

    Console.WriteLine();

    formatter = new BinaryFormatter();
    stream = new FileStream("c:\\test.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
    obj = (Random)formatter.Deserialize(stream);
    stream.Close();
    for (var i = 0; i < 10; i++)
        Console.WriteLine(obj.Next().ToString());

    Console.Read();
}

解决方案

It's serializable, so you may find you can just use BinaryFormatter and save the byte array...

Sample code:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class Program
{
    public static void Main(String[] args)
    {
        Random rng = new Random();
        Console.WriteLine("Values before saving...");
        ShowValues(rng);

        BinaryFormatter formatter = new BinaryFormatter(); 
        MemoryStream stream = new MemoryStream();
        formatter.Serialize(stream, rng);

        Console.WriteLine("Values after saving...");
        ShowValues(rng);

        stream.Position = 0; // Rewind ready for reading
        Random restored = (Random) formatter.Deserialize(stream);

        Console.WriteLine("Values after restoring...");
        ShowValues(restored);       
    }

    static void ShowValues(Random rng)
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(rng.Next(100));
        }
    }
}

Results on a sample run are promising:

Values before saving...
25
73
58
6
33
Values after saving...
71
7
87
3
77
Values after restoring...
71
7
87
3
77

Admittedly I'm not keen on the built-in serialization, but if this is for a reasonably quick and dirty hack, it should be okay...