LFSR 未按预期工作
LFSR not working as intended
如上所述,我创建了一个 LFSR 来尝试生成一些数字,但是它无法正常工作。
从这里开始:
unsigned int lfsr = 0x000001
while(1)
{
lfsr >>= 1
unsigned int lsb1 = lfsr & 1;
unsigned int lsb2 = lfsr & 2;
if (lsb1 == 1 && lsb2 == 1 || lsb1 == 0 && lsb2 == 0)
lfsr |= 0x000000;
else
lfsr |= 0x800000;
}
但是这没有用,因为 lsb2 等于 2,所以经过一番思考之后我现在得到了这个:
unsigned int lfsr = 0x000001
while(1)
{
lfsr >>= 1
lfsr |= ( (((unsigned int)((lfsr<<31)>>31)) ^ ((unsigned int)((lfsr<<30)>>31))) << 24);
}
这会生成 2^21 - 1 个数字,而我正在尝试生成 2^24 个数字。
我是不是遗漏了什么明显的东西?
如有任何帮助,我们将不胜感激。
代码不正确:lsb2 == 1
永远不会是真的
unsigned int lsb2 = lfsr & 2;
...
if (lsb1 == 1 && lsb2 == 1 .... // bad
应该是
if (lsb1 && lsb2 .... // better
同意@Olaf,考虑uint32_t
。
unsigned int lfsr = 0x000001 // actually int is 4 bytes so result is 0x00000001
while(1)
{
lfsr >>= 1 // now lfsr = 0
unsigned int lsb1 = lfsr & 1; // == 0
unsigned int lsb2 = lfsr & 2; // == 0
// the following line will 'work' however, it is always better/clearer
// to force the correct precedence via parens
// and lsb2 will be 0 or 2, never 1
if (lsb1 == 1 && lsb2 == 1 || lsb1 == 0 && lsb2 == 0)
lfsr |= 0x000000; // this will always be executed and makes no change to the value in 'lfsr'
else
lfsr |= 0x800000; // unsigned int is 4 bytes, so this is actually 0x00800000
}
这些 LFSR 示例将循环遍历 (2^24)-1 个数字(所有 2^24 个数字,但零除外)。第一个例子是异或与(反馈多项式)然后移动的伽罗瓦 LFSR。第二个例子是 Galois LFSR,它用(反馈多项式 >> 1)进行异或运算。第三个例子是斐波那契 LFSR。请注意,对于 0x000001 的 start_state,所有三个示例的 bit 的值遵循相同的模式,即使 Galois LFSR 和 Fibonacci LFSR 将遵循不同的模式。 0x100001b 是最小的反馈多项式,0x1c20001 是 (2^24)-1 个周期的最大 4 抽头反馈多项式。
此示例遵循 wiki Galios LFSR 示例,首先完成异或:
int main(int argc, char *argv[])
{
unsigned int period, bit, lfsr, start_state;
period = 0;
lfsr = start_state = 0x000001;
do
{
bit = lfsr&1; /* get bit */
lfsr ^= (0-bit)&0x100001b; /* toggle taps if bit was 1 */
lfsr >>= 1; /* shift lfsr */
++period;
}while(lfsr != start_state);
printf("%x\n", period); /* period will == 0xffffff */
return(0);
}
此示例遵循 wiki Galios LFSR 示例,但首先完成转换:
int main(int argc, char *argv[])
{
unsigned int period, bit, lfsr, start_state;
period = 0;
lfsr = start_state = 0x000001;
do
{
bit = lfsr & 1; /* get bit */
lfsr >>= 1; /* shift lfsr */
lfsr ^= (0-bit)&0x80000d; /* toggle taps if bit was 1 */
++period;
} while (lfsr != start_state);
printf("%x\n", period); /* period will == 0xffffff */
return(0);
}
此示例遵循 wiki 斐波那契 LFSR 示例:
int main(int argc, char *argv[])
{
unsigned int period, bit, lfsr, start_state;
period = 0;
lfsr = start_state = 0x000001;
do
{
/* taps: 24 4 3 1 */
/* feedback polynomial: x^24 + x^4 + x^3 + x + 1 = 0x100001b */
bit = ((lfsr>>(24-24))^(lfsr>>(24-4))^(lfsr>>(24-3))^(lfsr>>(24-1)))&1;
lfsr = (lfsr >> 1) | (bit << 23);
++period;
} while (lfsr != start_state);
printf("%x\n", period); /* period will == 0xffffff */
return(0);
}
如上所述,我创建了一个 LFSR 来尝试生成一些数字,但是它无法正常工作。
从这里开始:
unsigned int lfsr = 0x000001
while(1)
{
lfsr >>= 1
unsigned int lsb1 = lfsr & 1;
unsigned int lsb2 = lfsr & 2;
if (lsb1 == 1 && lsb2 == 1 || lsb1 == 0 && lsb2 == 0)
lfsr |= 0x000000;
else
lfsr |= 0x800000;
}
但是这没有用,因为 lsb2 等于 2,所以经过一番思考之后我现在得到了这个:
unsigned int lfsr = 0x000001
while(1)
{
lfsr >>= 1
lfsr |= ( (((unsigned int)((lfsr<<31)>>31)) ^ ((unsigned int)((lfsr<<30)>>31))) << 24);
}
这会生成 2^21 - 1 个数字,而我正在尝试生成 2^24 个数字。
我是不是遗漏了什么明显的东西? 如有任何帮助,我们将不胜感激。
代码不正确:lsb2 == 1
永远不会是真的
unsigned int lsb2 = lfsr & 2;
...
if (lsb1 == 1 && lsb2 == 1 .... // bad
应该是
if (lsb1 && lsb2 .... // better
同意@Olaf,考虑uint32_t
。
unsigned int lfsr = 0x000001 // actually int is 4 bytes so result is 0x00000001
while(1)
{
lfsr >>= 1 // now lfsr = 0
unsigned int lsb1 = lfsr & 1; // == 0
unsigned int lsb2 = lfsr & 2; // == 0
// the following line will 'work' however, it is always better/clearer
// to force the correct precedence via parens
// and lsb2 will be 0 or 2, never 1
if (lsb1 == 1 && lsb2 == 1 || lsb1 == 0 && lsb2 == 0)
lfsr |= 0x000000; // this will always be executed and makes no change to the value in 'lfsr'
else
lfsr |= 0x800000; // unsigned int is 4 bytes, so this is actually 0x00800000
}
这些 LFSR 示例将循环遍历 (2^24)-1 个数字(所有 2^24 个数字,但零除外)。第一个例子是异或与(反馈多项式)然后移动的伽罗瓦 LFSR。第二个例子是 Galois LFSR,它用(反馈多项式 >> 1)进行异或运算。第三个例子是斐波那契 LFSR。请注意,对于 0x000001 的 start_state,所有三个示例的 bit 的值遵循相同的模式,即使 Galois LFSR 和 Fibonacci LFSR 将遵循不同的模式。 0x100001b 是最小的反馈多项式,0x1c20001 是 (2^24)-1 个周期的最大 4 抽头反馈多项式。
此示例遵循 wiki Galios LFSR 示例,首先完成异或:
int main(int argc, char *argv[])
{
unsigned int period, bit, lfsr, start_state;
period = 0;
lfsr = start_state = 0x000001;
do
{
bit = lfsr&1; /* get bit */
lfsr ^= (0-bit)&0x100001b; /* toggle taps if bit was 1 */
lfsr >>= 1; /* shift lfsr */
++period;
}while(lfsr != start_state);
printf("%x\n", period); /* period will == 0xffffff */
return(0);
}
此示例遵循 wiki Galios LFSR 示例,但首先完成转换:
int main(int argc, char *argv[])
{
unsigned int period, bit, lfsr, start_state;
period = 0;
lfsr = start_state = 0x000001;
do
{
bit = lfsr & 1; /* get bit */
lfsr >>= 1; /* shift lfsr */
lfsr ^= (0-bit)&0x80000d; /* toggle taps if bit was 1 */
++period;
} while (lfsr != start_state);
printf("%x\n", period); /* period will == 0xffffff */
return(0);
}
此示例遵循 wiki 斐波那契 LFSR 示例:
int main(int argc, char *argv[])
{
unsigned int period, bit, lfsr, start_state;
period = 0;
lfsr = start_state = 0x000001;
do
{
/* taps: 24 4 3 1 */
/* feedback polynomial: x^24 + x^4 + x^3 + x + 1 = 0x100001b */
bit = ((lfsr>>(24-24))^(lfsr>>(24-4))^(lfsr>>(24-3))^(lfsr>>(24-1)))&1;
lfsr = (lfsr >> 1) | (bit << 23);
++period;
} while (lfsr != start_state);
printf("%x\n", period); /* period will == 0xffffff */
return(0);
}