|
|
1.1 root 1: /*
2: ** lfsr.c - Linear Feedback Shift Register (LFSR) routines.
3: ** (c) 1988 Philip Zimmermann. All rights reserved.
4: ** 10 Sep 88 -- revised 20 Jun 89
5: */
6:
7: #include "lfsr.h" /* Linear Feedback Shift Register headers */
8:
9: /* Calling routines must declare lfsr buffer and byte index into it.: */
10: /* byte lfsr[256] = {0}; */
11: /* byte rtail = 0; /* points to 256, which is same as 0 */
12:
13:
14: /*
15: ** steplfsr256 - Step big linear feedback shift register (LFSR)
16: ** 256 cycles. Use primitive polynomial: X^255 + X^82 + X^0
17: ** Actually runs 8 LFSR's in parallel, outputting a whole byte
18: ** with each step.
19: */
20: void steplfsr256(register byteptr lfsr)
21: { register byte ltail;
22: register byte ltap0;
23: register byte ltap82;
24: register byte ltap255;
25: ltail = 0; ltap0 = 0; ltap82 = 82; ltap255 = 255;
26: do
27: lfsr[--ltail] = lfsr[ltap0--]^lfsr[ltap82--]^lfsr[ltap255--];
28: while (ltail);
29: } /* steplfsr256 */
30:
31:
32: /*
33: ** getlfsr - get 1 byte from lfsr buffer.
34: ** Calls steplfsr256() if necessary to replenish lfsr buffer.
35: **
36: ** getlfsr() is a #define in the header file "lfsr.h"
37: */
38:
39:
40: /*
41: ** initlfsr - initialize linear feedback shift register
42: **
43: ** Since each of the 8 bits of the bytes in the LFSR array represents
44: ** a separate independant LFSR, we must be sure the every one of the
45: ** 8 LFSRs have some 1's and 0's in it. Therefore, an unmodified
46: ** 7-bit ASCII string is not an acceptable seed for the LFSR byte
47: ** array, because the high bits are all zeros. That's why we do a
48: ** cumulative add on the seed bits, to mix the seed bits up between
49: ** the 8 LFSRs.
50: */
51: void initlfsr(byteptr seed, short size, byteptr lfsr, byte *rtail)
52: /* seed is random number seed.
53: size is number of bytes in seed.
54: lfsr is pointer to 256-byte LFSR buffer.
55: *rtail is rtail index byte.
56: */
57: { short i;
58: unsigned int c;
59: #ifdef CHECKLFSR
60: byte check1,check0; /* to ensure 1s and 0s mixed in each LFSR */
61: check0 = 0x00; /* should end up as 0xff after ORing */
62: check1 = 0xff; /* should end up as 0x00 after ANDing */
63: #endif /* CHECKLFSR */
64: *rtail = 0; /* points to 256, which is same as 0 */
65: c = size; /* makes seed "AAA" distinct from seed "AAAAAA" */
66: for (i=0; i<=255; i++) /* make several seed copies across the LFSR */
67: { c += seed[i % size]; /* cumulatively add the seed data */
68: lfsr[i] = c + (c>>8); /* wraparound carry bits */
69: #ifdef CHECKLFSR
70: check0 |= lfsr[i]; /* scan for all zeros in any LFSR row */
71: check1 &= lfsr[i]; /* scan for all ones in any LFSR row */
72: #endif /* CHECKLFSR */
73: }
74: #ifdef CHECKLFSR
75: /* if any LFSR row contained all zeros, check0 will not be 0xff */
76: /* if any LFSR row contained all ones, check1 will not be 0x00 */
77: c = 0xFF & (check1 | ~check0); /* should be 0x00 if all went OK. */
78: /* Now guarantee that all 8 LFSRs contain a mix of 1s and 0s... */
79: if (c) printf("\nLFSR check0=%2X check1=%2X. ",check0,check1);
80: lfsr[0] ^= c; /* flip some faulty bits if we have to */
81: #endif /* CHECKLFSR */
82: } /* initlfsr */
83:
84:
85: /*
86: ** stomplfsr - inverts about half the bits in an LFSR.
87: **
88: ** If the LFSR has a "rail" of almost all 0's or almost all 1's in
89: ** the same bit position, it will perform poorly as a random number
90: ** generator. This function will probably fix this condition.
91: */
92: void stomplfsr(byteptr lfsr)
93: /* lfsr is pointer to 256-byte LFSR buffer. */
94: { byte i;
95: i=255;
96: while (i) *lfsr++ ^= i--;
97: } /* stomplfsr */
98:
99:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.