我正在使用generalized Feistel network生成置换,该置换将根据计数器伪随机地输出指定范围[0,周期]中指定范围内的无符号整数值,然后在精确地到达每个整数一次之后循环(而不保持内部状态。
我不是将计数器分为两个相等大小的位向量L
和R
,而是对商和余数进行运算,方法是通过返回商*除数+余数来重新组合。这允许任何周期的排列(不仅是那些2的幂,like an LSFR):
uint16_t feistel(uint16_t counter, unsigned period)
{
uint16_t d = sqrt(period);
uint16_t s = period - d*d;
uint16_t q = counter / d;
uint16_t r = counter % s;
for (int i = 0; i < 3; i++)
{
uint16_t nr = r;
/* a simple insecure round function */
uint16_t F = (i * r + q);
r = F % d;
q = nr;
}
return q*d + r;
}
此代码 可以正确生成一些最大排列(即[feistel(N)...feistel(N+period)]
包含[0, period]
之间的每个数字,随机排列)。
但是,它仅对平方数的周期(s
= 0)有效。
是否可以更改此格式,以便任何周期选择都能生成完整的排列?