Xorshift和所有LFSR类型的发生器将嘎然而止,如果用全零状态播种它就什么都不做。它出现(如果我的测试中没有错误),则表示以下功能:
y = one_xorshift_round(y)
y = y ^ key
将抵抗这种锁定,因为y的任何非零状态都将产生对某个随机值的更改,并且任何为零的状态将通过该键与其他状态进行异或。如果键导致它落在零上,它将在下一轮修复它。
我想你会得到每个“关键”值产生不同序列的额外好处。
我的应用程序是一个Arduino库,需要统计上随机数,根本不需要任何加密强度,但不能一遍又一遍地重复相同的循环。我想要做的是使用自电路板上电以来的当前微秒数,这应该在每次使用时为RNG添加一些熵(由于用户引起的确切时间的不确定性)输入等),也导致随机序列随时间变化,人为伪造的时间更长。
我的问题是,键值或简单的变量键模式是否会导致XORSHIFT生成器做坏事,比如输入一个短周期?我想,实际弄清楚它的数学会非常复杂,但也许有人提到了纸张或类似的东西和一个类似修改过的RNG?
谢谢!
编辑,附加信息:我对全零状态问题的第一反应是每一轮向状态添加1,但我发现向状态添加常量会使周期减少一个随着不变但似乎没有任何简单的模式。
答案 0 :(得分:2)
密钥导致短循环的最简单情况是密钥是独占值或一个值以及来自原始生成器的连续值。这会产生将状态重置为其先前值的效果,因此它只能产生一个输出。
如果该关键值对于来自原始生成器的许多不同输出对是相同的那么这将代表随机性测试中的严重失败,因此更有可能有许多不同的值可以有效地进入一个阶段回到周期中不同点的周期。
因此,假设您的密钥的许多值可以通过最终将其捕获在单值轨道中来缩短生成器的周期,这可能是公平的。然后有更复杂的情况导致更长的轨道仍然不是整个时期,但这些更难以思考。
您可能想要做的是分别收集熵并使用它来缓和PRNG的输出,而不会破坏PRNG本身的质量。例如,
void add_entropy(uint32_t more)
{
entropy = one_xorshift_round(entropy + more);
}
uint32_t rand(void)
{
y = one_xorshift_round(y);
return one_xorshift_round(y + entropy);
}
答案 1 :(得分:1)
我不会过多地使用随机生成器(比如任意改变状态空间),因为它的良好统计特性可能会消失。
测试种子并非全是零并不是坏事:这就是在这种发电机中所做的事情。如果你想要注入熵,只需要在状态空间上xor你的熵位,如果你得到所有的零,只需要输入一些常量。如果状态空间足够大,则概率很低,以至于您输入的内容不相关。在这种情况下,许多已发布的生成器使用生成器的名称(作为ASCII值序列)来生成生成器! :)
但是我建议您尝试一些64位变体,例如xorshift * / xorshift +,因为它们比纯xorshift生成器具有更好的统计属性。您可以在http://prng.di.unimi.it/
找到最新报告