【发布时间】:2016-02-21 19:31:31
【问题描述】:
我需要创建一个 Web 服务来接收一些数据并返回一个随机数。随机数必须由 Mersenne Twister 算法生成。
其中一个规范是为 Mersenne Twister 播种。因为是 Web 服务,所以我必须在每个请求中使用新种子为 Mersenne 对象播种吗?
【问题讨论】:
标签: c# web-services random-seed mersenne-twister
我需要创建一个 Web 服务来接收一些数据并返回一个随机数。随机数必须由 Mersenne Twister 算法生成。
其中一个规范是为 Mersenne Twister 播种。因为是 Web 服务,所以我必须在每个请求中使用新种子为 Mersenne 对象播种吗?
【问题讨论】:
标签: c# web-services random-seed mersenne-twister
与每个伪随机生成器一样,生成的输出列表是使用所述种子创建的。如果您提供相同的种子,则生成的序列输出将始终相同。所以你应该问你想要一个恒定的序列还是一个真正随机的序列。
回答你的问题:
您可以在 WebService 中使用静态常量值(如果担心安全性,我不建议这样做),或者您可以使用类似的东西:
long next_seed = DateTime.Now.Ticks ^ someValue;
生成“随机”种子。
希望对你有帮助
【讨论】:
newed,所以他不必提供一个种子值来保持它的随机性。他/她可以初始化 PRNG 类并让它使用默认的DateTime.Now.Ticks,因为它不容易被猜到。然而,就我个人而言,我不会那样做,我会写一个类,这样我就可以完全控制播种过程。
这是一个 Web 服务,因此该类将在每次调用时从头开始初始化并重新播种,除非您创建 Mersenne Twister 随机器类实例 static,因此不需要重新播种。但是,如果您这样做,您应该每隔一段时间重新初始化(销毁/重新创建)实例,因为 Mersenne Twister 的值在 600 次拉动后是可以猜测的。
为了提高性能,最好创建一个静态实例并按照以下伪代码每 500 次拉取重新初始化一次:
class RandomNumberGenerator
{
static MersenneTwisterClass RNG = null;
static object RNGLock = new object();
static int counter = 0;
public RandomNumberGenerator()
{
Init();
}
void Init()
{
// Multithreading lock
lock (RNGLock)
{
// Seed it or don't, your call
RNG = new MersenneTwisterClass(some_seed_value_or_nah);
counter = 0;
}
}
public decimal GetValue()
{
lock (RNGLock)
{
counter++;
if (counter > 500)
{
Init();
}
return RNG.GetValue();
}
}
public long GetRange(long min, long max)
{
lock (RNGLock)
{
counter++;
if (counter > 500)
{
Init();
}
return RNG.GetRange(min, max);
}
}
}
【讨论】: