我需要一个伪随机生成器,它将一个数字作为输入并返回另一个可重现的数字,并且似乎是随机的。
它一定不是完美的,它只是创建随机但可重现的测试数据。
我使用C#。
我前段时间编写了这段有趣的代码,它产生了随机的东西。
public static long Scramble(long number, long max)
{
// some random values
long[] scramblers = { 3, 5, 7, 31, 343, 2348, 89897 };
number += (max / 7) + 6;
number %= max;
// shuffle according to divisibility
foreach (long scrambler in scramblers)
{
if (scrambler >= max / 3) break;
number = ((number * scrambler) % max)
+ ((number * scrambler) / max);
}
return number % max;
}
我希望有更好,更可靠的东西,使用任何数量的大小(没有最大参数)。
这可能是使用CRC算法解决的吗?或者有点洗牌。
答案 0 :(得分:4)
我从这个答案中删除了微软代码,GNU代码文件要长得多,但基本上它包含来自http://cs.uccs.edu/~cs591/bufferOverflow/glibc-2.2.4/stdlib/random_r.c:
int32_t val = state[0];
val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
state[0] = val;
*result = val;
为了你的目的,种子是状态[0]所以它看起来更像
int getRand(int val)
{
return ((val * 1103515245) + 12345) & 0x7fffffff;
}
答案 1 :(得分:3)
您(也许)可以使用Random类在C#中轻松完成此任务:
public int GetPseudoRandomNumber(int input)
{
Random random = new Random(input);
return random.Next();
}
由于您使用输入显式播种Random,因此每次给定相同的输入值时,您将获得相同的输出。
答案 2 :(得分:1)
前两条规则建议输入的固定或输入种子排列,但第三条规则需要进一步转换。
对输出应该是什么有进一步的限制,以指导这种转变? - 例如是否有一组输入值可供选择?
如果唯一指南是“no max”,我会使用以下内容......
将哈希算法应用于整个输入以获取第一个输出项。 CRC可能有效,但对于更多“随机”结果,请使用加密哈希算法,例如MD5。
在输入上使用下一个排列算法(Google上有大量链接)。
重复hash-then-next-permutation,直到找到所有必需的输出。
下一个排列可能有点矫枉过正,你可能只是在重做哈希值之前增加第一个输入(也许,在溢出时增加第二个等等)。
对于加密样式哈希,你需要一个密钥 - 在开始之前从输入中获取一些东西。
答案 3 :(得分:1)
tausworthe发电机易于实施且速度非常快。以下伪代码实现具有完整周期(2 ** 31 - 1,因为零是固定点):
def tausworthe(seed)
seed ^= seed >> 13
seed ^= seed << 18
return seed & 0x7fffffff
我不知道C#,但我假设它具有XOR(^
)和位移(<<
,>>
)运算符,如C中所示。
设置初始种子值,并使用seed = tausworthe(seed)
调用。