1 /* 2 * 3 * Copyright (c) 2001-2006, Cisco Systems, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * Neither the name of the Cisco Systems, Inc. nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 33 * OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 */ 36 /* 37 * lfsr.c 38 * 39 */ 40 41 42 #include <stdio.h> 43 #include "datatypes.h" 44 45 uint32_t 46 parity(uint32_t x) { 47 48 x ^= (x >> 16); 49 x ^= (x >> 8); 50 x ^= (x >> 4); 51 x ^= (x >> 2); 52 x ^= (x >> 1); 53 54 return x & 1; 55 } 56 57 58 /* typedef struct { */ 59 /* uint32_t register[8]; */ 60 /* } lfsr_t; */ 61 62 void 63 compute_period(uint32_t feedback_polynomial) { 64 int i; 65 v32_t lfsr; 66 v32_t mask; 67 68 mask.value = feedback_polynomial; 69 lfsr.value = 1; 70 71 printf("polynomial: %s\t", v32_bit_string(mask)); 72 73 for (i=0; i < 256; i++) { 74 /* printf("%s\n", v32_bit_string(lfsr)); */ 75 if (parity(mask.value & lfsr.value)) 76 lfsr.value = ((lfsr.value << 1) | 1) & 0xff; 77 else 78 lfsr.value = (lfsr.value << 1) & 0xff; 79 80 /* now halt if we're back at the initial state */ 81 if (lfsr.value == 1) { 82 printf("period: %d\n", i); 83 break; 84 } 85 } 86 } 87 88 uint32_t poly0 = 223; 89 90 91 uint32_t polynomials[39] = { 92 31, 93 47, 94 55, 95 59, 96 61, 97 79, 98 87, 99 91, 100 103, 101 107, 102 109, 103 115, 104 117, 105 121, 106 143, 107 151, 108 157, 109 167, 110 171, 111 173, 112 179, 113 181, 114 185, 115 199, 116 203, 117 205, 118 211, 119 213, 120 227, 121 229, 122 233, 123 241, 124 127, 125 191, 126 223, 127 239, 128 247, 129 251, 130 253 131 }; 132 133 char binary_string[32]; 134 135 char * 136 u32_bit_string(uint32_t x, unsigned int length) { 137 unsigned int mask; 138 int index; 139 140 mask = 1 << length; 141 index = 0; 142 for (; mask > 0; mask >>= 1) 143 if ((x & mask) == 0) 144 binary_string[index++] = '0'; 145 else 146 binary_string[index++] = '1'; 147 148 binary_string[index++] = 0; /* NULL terminate string */ 149 return binary_string; 150 } 151 152 extern int octet_weight[256]; 153 154 unsigned int 155 weight(uint32_t poly) { 156 int wt = 0; 157 158 /* note: endian-ness makes no difference */ 159 wt += octet_weight[poly & 0xff]; 160 wt += octet_weight[(poly >> 8) & 0xff]; 161 wt += octet_weight[(poly >> 16) & 0xff]; 162 wt += octet_weight[(poly >> 24)]; 163 164 return wt; 165 } 166 167 #define MAX_PERIOD 65535 168 169 #define debug_print 0 170 171 int 172 period(uint32_t poly) { 173 int i; 174 uint32_t x; 175 176 177 /* set lfsr to 1 */ 178 x = 1; 179 #if debug_print 180 printf("%d:\t%s\n", 0, u32_bit_string(x,8)); 181 #endif 182 for (i=1; i < MAX_PERIOD; i++) { 183 if (x & 1) 184 x = (x >> 1) ^ poly; 185 else 186 x = (x >> 1); 187 188 #if debug_print 189 /* print for a sanity check */ 190 printf("%d:\t%s\n", i, u32_bit_string(x,8)); 191 #endif 192 193 /* check for return to original value */ 194 if (x == 1) 195 return i; 196 } 197 return i; 198 } 199 200 /* 201 * weight distribution computes the weight distribution of the 202 * code generated by the polynomial poly 203 */ 204 205 #define MAX_LEN 8 206 #define MAX_WEIGHT (1 << MAX_LEN) 207 208 int A[MAX_WEIGHT+1]; 209 210 void 211 weight_distribution2(uint32_t poly, int *A) { 212 int i; 213 uint32_t x; 214 215 /* zeroize array */ 216 for (i=0; i < MAX_WEIGHT+1; i++) 217 A[i] = 0; 218 219 /* loop over all input sequences */ 220 221 222 /* set lfsr to 1 */ 223 x = 1; 224 #if debug_print 225 printf("%d:\t%s\n", 0, u32_bit_string(x,8)); 226 #endif 227 for (i=1; i < MAX_PERIOD; i++) { 228 if (x & 1) 229 x = (x >> 1) ^ poly; 230 else 231 x = (x >> 1); 232 233 #if debug_print 234 /* print for a sanity check */ 235 printf("%d:\t%s\n", i, u32_bit_string(x,8)); 236 #endif 237 238 /* increment weight */ 239 wt += (x & 1); 240 241 /* check for return to original value */ 242 if (x == 1) 243 break; 244 } 245 246 /* set zero */ 247 A[0] = 0; 248 } 249 250 251 void 252 weight_distribution(uint32_t poly, int *A) { 253 int i; 254 uint32_t x; 255 256 /* zeroize array */ 257 for (i=0; i < MAX_WEIGHT+1; i++) 258 A[i] = 0; 259 260 /* set lfsr to 1 */ 261 x = 1; 262 #if debug_print 263 printf("%d:\t%s\n", 0, u32_bit_string(x,8)); 264 #endif 265 for (i=1; i < MAX_PERIOD; i++) { 266 if (x & 1) 267 x = (x >> 1) ^ poly; 268 else 269 x = (x >> 1); 270 271 #if debug_print 272 /* print for a sanity check */ 273 printf("%d:\t%s\n", i, u32_bit_string(x,8)); 274 #endif 275 276 /* compute weight, increment proper element */ 277 A[weight(x)]++; 278 279 /* check for return to original value */ 280 if (x == 1) 281 break; 282 } 283 284 /* set zero */ 285 A[0] = 0; 286 } 287 288 289 290 291 int 292 main () { 293 294 int i,j; 295 v32_t x; 296 v32_t p; 297 298 /* originally 0xaf */ 299 p.value = 0x9; 300 301 printf("polynomial: %s\tperiod: %d\n", 302 u32_bit_string(p.value,8), period(p.value)); 303 304 /* compute weight distribution */ 305 weight_distribution(p.value, A); 306 307 /* print weight distribution */ 308 for (i=0; i <= 8; i++) { 309 printf("A[%d]: %d\n", i, A[i]); 310 } 311 312 #if 0 313 for (i=0; i < 39; i++) { 314 printf("polynomial: %s\tperiod: %d\n", 315 u32_bit_string(polynomials[i],8), period(polynomials[i])); 316 317 /* compute weight distribution */ 318 weight_distribution(p.value, A); 319 320 /* print weight distribution */ 321 for (j=0; j <= 8; j++) { 322 printf("A[%d]: %d\n", j, A[j]); 323 } 324 } 325 #endif 326 327 { 328 int bits = 8; 329 uint32_t y; 330 for (y=0; y < (1 << bits); y++) { 331 printf("polynomial: %s\tweight: %d\tperiod: %d\n", 332 u32_bit_string(y,bits), weight(y), period(y)); 333 334 /* compute weight distribution */ 335 weight_distribution(y, A); 336 337 /* print weight distribution */ 338 for (j=0; j <= 8; j++) { 339 printf("A[%d]: %d\n", j, A[j]); 340 } 341 } 342 } 343 344 return 0; 345 } 346