home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hacker Chronicles 2
/
HACKER2.BIN
/
1212.LFSR.C
< prev
next >
Wrap
Text File
|
1991-01-06
|
3KB
|
100 lines
/*
** lfsr.c - Linear Feedback Shift Register (LFSR) routines.
** (c) 1988 Philip Zimmermann. All rights reserved.
** 10 Sep 88 -- revised 20 Jun 89
*/
#include "lfsr.h" /* Linear Feedback Shift Register headers */
/* Calling routines must declare lfsr buffer and byte index into it.: */
/* byte lfsr[256] = {0}; */
/* byte rtail = 0; /* points to 256, which is same as 0 */
/*
** steplfsr256 - Step big linear feedback shift register (LFSR)
** 256 cycles. Use primitive polynomial: X^255 + X^82 + X^0
** Actually runs 8 LFSR's in parallel, outputting a whole byte
** with each step.
*/
void steplfsr256(register byteptr lfsr)
{ register byte ltail;
register byte ltap0;
register byte ltap82;
register byte ltap255;
ltail = 0; ltap0 = 0; ltap82 = 82; ltap255 = 255;
do
lfsr[--ltail] = lfsr[ltap0--]^lfsr[ltap82--]^lfsr[ltap255--];
while (ltail);
} /* steplfsr256 */
/*
** getlfsr - get 1 byte from lfsr buffer.
** Calls steplfsr256() if necessary to replenish lfsr buffer.
**
** getlfsr() is a #define in the header file "lfsr.h"
*/
/*
** initlfsr - initialize linear feedback shift register
**
** Since each of the 8 bits of the bytes in the LFSR array represents
** a separate independant LFSR, we must be sure the every one of the
** 8 LFSRs have some 1's and 0's in it. Therefore, an unmodified
** 7-bit ASCII string is not an acceptable seed for the LFSR byte
** array, because the high bits are all zeros. That's why we do a
** cumulative add on the seed bits, to mix the seed bits up between
** the 8 LFSRs.
*/
void initlfsr(byteptr seed, short size, byteptr lfsr, byte *rtail)
/* seed is random number seed.
size is number of bytes in seed.
lfsr is pointer to 256-byte LFSR buffer.
*rtail is rtail index byte.
*/
{ short i;
unsigned int c;
#ifdef CHECKLFSR
byte check1,check0; /* to ensure 1s and 0s mixed in each LFSR */
check0 = 0x00; /* should end up as 0xff after ORing */
check1 = 0xff; /* should end up as 0x00 after ANDing */
#endif /* CHECKLFSR */
*rtail = 0; /* points to 256, which is same as 0 */
c = size; /* makes seed "AAA" distinct from seed "AAAAAA" */
for (i=0; i<=255; i++) /* make several seed copies across the LFSR */
{ c += seed[i % size]; /* cumulatively add the seed data */
lfsr[i] = c + (c>>8); /* wraparound carry bits */
#ifdef CHECKLFSR
check0 |= lfsr[i]; /* scan for all zeros in any LFSR row */
check1 &= lfsr[i]; /* scan for all ones in any LFSR row */
#endif /* CHECKLFSR */
}
#ifdef CHECKLFSR
/* if any LFSR row contained all zeros, check0 will not be 0xff */
/* if any LFSR row contained all ones, check1 will not be 0x00 */
c = 0xFF & (check1 | ~check0); /* should be 0x00 if all went OK. */
/* Now guarantee that all 8 LFSRs contain a mix of 1s and 0s... */
if (c) printf("\nLFSR check0=%2X check1=%2X. ",check0,check1);
lfsr[0] ^= c; /* flip some faulty bits if we have to */
#endif /* CHECKLFSR */
} /* initlfsr */
/*
** stomplfsr - inverts about half the bits in an LFSR.
**
** If the LFSR has a "rail" of almost all 0's or almost all 1's in
** the same bit position, it will perform poorly as a random number
** generator. This function will probably fix this condition.
*/
void stomplfsr(byteptr lfsr)
/* lfsr is pointer to 256-byte LFSR buffer. */
{ byte i;
i=255;
while (i) *lfsr++ ^= i--;
} /* stomplfsr */