forked from Mirrors/freeswitch
b3d890ef25
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1086 d0543943-73ff-0310-b7d9-9358b9ac24b2
311 lines
4.8 KiB
C
311 lines
4.8 KiB
C
/*
|
|
* lfsr.c
|
|
*
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include "datatypes.h"
|
|
|
|
uint32_t
|
|
parity(uint32_t x) {
|
|
|
|
x ^= (x >> 16);
|
|
x ^= (x >> 8);
|
|
x ^= (x >> 4);
|
|
x ^= (x >> 2);
|
|
x ^= (x >> 1);
|
|
|
|
return x & 1;
|
|
}
|
|
|
|
|
|
/* typedef struct { */
|
|
/* uint32_t register[8]; */
|
|
/* } lfsr_t; */
|
|
|
|
void
|
|
compute_period(uint32_t feedback_polynomial) {
|
|
int i;
|
|
v32_t lfsr;
|
|
v32_t mask;
|
|
|
|
mask.value = feedback_polynomial;
|
|
lfsr.value = 1;
|
|
|
|
printf("polynomial: %s\t", v32_bit_string(mask));
|
|
|
|
for (i=0; i < 256; i++) {
|
|
/* printf("%s\n", v32_bit_string(lfsr)); */
|
|
if (parity(mask.value & lfsr.value))
|
|
lfsr.value = ((lfsr.value << 1) | 1) & 0xff;
|
|
else
|
|
lfsr.value = (lfsr.value << 1) & 0xff;
|
|
|
|
/* now halt if we're back at the initial state */
|
|
if (lfsr.value == 1) {
|
|
printf("period: %d\n", i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32_t poly0 = 223;
|
|
|
|
|
|
uint32_t polynomials[39] = {
|
|
31,
|
|
47,
|
|
55,
|
|
59,
|
|
61,
|
|
79,
|
|
87,
|
|
91,
|
|
103,
|
|
107,
|
|
109,
|
|
115,
|
|
117,
|
|
121,
|
|
143,
|
|
151,
|
|
157,
|
|
167,
|
|
171,
|
|
173,
|
|
179,
|
|
181,
|
|
185,
|
|
199,
|
|
203,
|
|
205,
|
|
211,
|
|
213,
|
|
227,
|
|
229,
|
|
233,
|
|
241,
|
|
127,
|
|
191,
|
|
223,
|
|
239,
|
|
247,
|
|
251,
|
|
253
|
|
};
|
|
|
|
char binary_string[32];
|
|
|
|
char *
|
|
u32_bit_string(uint32_t x, unsigned int length) {
|
|
unsigned int mask;
|
|
int index;
|
|
|
|
mask = 1 << length;
|
|
index = 0;
|
|
for (; mask > 0; mask >>= 1)
|
|
if ((x & mask) == 0)
|
|
binary_string[index++] = '0';
|
|
else
|
|
binary_string[index++] = '1';
|
|
|
|
binary_string[index++] = 0; /* NULL terminate string */
|
|
return binary_string;
|
|
}
|
|
|
|
extern int octet_weight[256];
|
|
|
|
unsigned int
|
|
weight(uint32_t poly) {
|
|
int wt = 0;
|
|
|
|
/* note: endian-ness makes no difference */
|
|
wt += octet_weight[poly & 0xff];
|
|
wt += octet_weight[(poly >> 8) & 0xff];
|
|
wt += octet_weight[(poly >> 16) & 0xff];
|
|
wt += octet_weight[(poly >> 24)];
|
|
|
|
return wt;
|
|
}
|
|
|
|
#define MAX_PERIOD 65535
|
|
|
|
#define debug_print 0
|
|
|
|
int
|
|
period(uint32_t poly) {
|
|
int i;
|
|
uint32_t x;
|
|
|
|
|
|
/* set lfsr to 1 */
|
|
x = 1;
|
|
#if debug_print
|
|
printf("%d:\t%s\n", 0, u32_bit_string(x,8));
|
|
#endif
|
|
for (i=1; i < MAX_PERIOD; i++) {
|
|
if (x & 1)
|
|
x = (x >> 1) ^ poly;
|
|
else
|
|
x = (x >> 1);
|
|
|
|
#if debug_print
|
|
/* print for a sanity check */
|
|
printf("%d:\t%s\n", i, u32_bit_string(x,8));
|
|
#endif
|
|
|
|
/* check for return to original value */
|
|
if (x == 1)
|
|
return i;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
/*
|
|
* weight distribution computes the weight distribution of the
|
|
* code generated by the polynomial poly
|
|
*/
|
|
|
|
#define MAX_LEN 8
|
|
#define MAX_WEIGHT (1 << MAX_LEN)
|
|
|
|
int A[MAX_WEIGHT+1];
|
|
|
|
void
|
|
weight_distribution2(uint32_t poly, int *A) {
|
|
int i;
|
|
uint32_t x;
|
|
|
|
/* zeroize array */
|
|
for (i=0; i < MAX_WEIGHT+1; i++)
|
|
A[i] = 0;
|
|
|
|
/* loop over all input sequences */
|
|
|
|
|
|
/* set lfsr to 1 */
|
|
x = 1;
|
|
#if debug_print
|
|
printf("%d:\t%s\n", 0, u32_bit_string(x,8));
|
|
#endif
|
|
for (i=1; i < MAX_PERIOD; i++) {
|
|
if (x & 1)
|
|
x = (x >> 1) ^ poly;
|
|
else
|
|
x = (x >> 1);
|
|
|
|
#if debug_print
|
|
/* print for a sanity check */
|
|
printf("%d:\t%s\n", i, u32_bit_string(x,8));
|
|
#endif
|
|
|
|
/* increment weight */
|
|
wt += (x & 1);
|
|
|
|
/* check for return to original value */
|
|
if (x == 1)
|
|
break;
|
|
}
|
|
|
|
/* set zero */
|
|
A[0] = 0;
|
|
}
|
|
|
|
|
|
void
|
|
weight_distribution(uint32_t poly, int *A) {
|
|
int i;
|
|
uint32_t x;
|
|
|
|
/* zeroize array */
|
|
for (i=0; i < MAX_WEIGHT+1; i++)
|
|
A[i] = 0;
|
|
|
|
/* set lfsr to 1 */
|
|
x = 1;
|
|
#if debug_print
|
|
printf("%d:\t%s\n", 0, u32_bit_string(x,8));
|
|
#endif
|
|
for (i=1; i < MAX_PERIOD; i++) {
|
|
if (x & 1)
|
|
x = (x >> 1) ^ poly;
|
|
else
|
|
x = (x >> 1);
|
|
|
|
#if debug_print
|
|
/* print for a sanity check */
|
|
printf("%d:\t%s\n", i, u32_bit_string(x,8));
|
|
#endif
|
|
|
|
/* compute weight, increment proper element */
|
|
A[weight(x)]++;
|
|
|
|
/* check for return to original value */
|
|
if (x == 1)
|
|
break;
|
|
}
|
|
|
|
/* set zero */
|
|
A[0] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
main () {
|
|
|
|
int i,j;
|
|
v32_t x;
|
|
v32_t p;
|
|
|
|
/* originally 0xaf */
|
|
p.value = 0x9;
|
|
|
|
printf("polynomial: %s\tperiod: %d\n",
|
|
u32_bit_string(p.value,8), period(p.value));
|
|
|
|
/* compute weight distribution */
|
|
weight_distribution(p.value, A);
|
|
|
|
/* print weight distribution */
|
|
for (i=0; i <= 8; i++) {
|
|
printf("A[%d]: %d\n", i, A[i]);
|
|
}
|
|
|
|
#if 0
|
|
for (i=0; i < 39; i++) {
|
|
printf("polynomial: %s\tperiod: %d\n",
|
|
u32_bit_string(polynomials[i],8), period(polynomials[i]));
|
|
|
|
/* compute weight distribution */
|
|
weight_distribution(p.value, A);
|
|
|
|
/* print weight distribution */
|
|
for (j=0; j <= 8; j++) {
|
|
printf("A[%d]: %d\n", j, A[j]);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
{
|
|
int bits = 8;
|
|
uint32_t y;
|
|
for (y=0; y < (1 << bits); y++) {
|
|
printf("polynomial: %s\tweight: %d\tperiod: %d\n",
|
|
u32_bit_string(y,bits), weight(y), period(y));
|
|
|
|
/* compute weight distribution */
|
|
weight_distribution(y, A);
|
|
|
|
/* print weight distribution */
|
|
for (j=0; j <= 8; j++) {
|
|
printf("A[%d]: %d\n", j, A[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|