LFSR无法按预期工作

时间:2015-09-08 15:19:24

标签: c bit-shift bits

如上所述,我创建了一个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的数字。

我错过了一些明显的东西吗? 任何帮助将不胜感激,谢谢。

3 个答案:

答案 0 :(得分:1)

这些LFSR示例将循环通过(2 ^ 24)-1个数字(所有2 ^ 24个数字,但为零)。第一个例子是伽罗瓦LFSR,然后xor(反馈多项式)移位。第二个例子是伽罗瓦LFSR,然后用(反馈多项式&gt;> 1)移位xor。第三个例子是Fibonacci LFSR。请注意,对于start_state为0x000001,所有三个示例的 bit 的值遵循相同的模式,即使Galois LFSR和Fibonacci LFSR将遵循不同的模式。 0x100001b是最小的反馈多项式,0x1c20001是(2 ^ 24)-1个周期的最大4抽头反馈多项式。

此示例遵循wiki Galios LFSR示例,首先执行xor:

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示例,首先执行shift:

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 Fibonacci 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);
}

答案 1 :(得分:0)

代码不正确:lsb2 == 1永远不会是真的

unsigned int lsb2 = lfsr & 2;
...
if (lsb1 == 1 && lsb2 == 1 ....  // bad

可能应该是

if (lsb1 && lsb2 ....  // better

同意@Olaf,请考虑uint32_t

答案 2 :(得分:0)

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
}