00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018 #include <math.h>
00019
00020 #include "bytes.h"
00021 #include "bits.h"
00022
00023 #include "bch.h"
00024 #include "input.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 static int m, n, length, k, t, d;
00049 static int p[21];
00050 static int alpha_to[1048576], index_of[1048576], g[548576];
00051 static int recd[1048576], data[1048576], bb[548576];
00052
00053 extern int debug;
00054
00055
00056
00057
00058 static void
00059 generate_gf()
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 {
00071 register int i, mask;
00072
00073 mask = 1;
00074 alpha_to[m] = 0;
00075 for (i = 0; i < m; i++) {
00076 alpha_to[i] = mask;
00077 index_of[alpha_to[i]] = i;
00078 if (p[i] != 0)
00079 alpha_to[m] ^= mask;
00080 mask <<= 1;
00081 }
00082 index_of[alpha_to[m]] = m;
00083 mask >>= 1;
00084 for (i = m + 1; i < n; i++) {
00085 if (alpha_to[i - 1] >= mask)
00086 alpha_to[i] = alpha_to[m] ^ ((alpha_to[i - 1] ^ mask) << 1);
00087 else
00088 alpha_to[i] = alpha_to[i - 1] << 1;
00089 index_of[alpha_to[i]] = i;
00090 }
00091 index_of[0] = -1;
00092 }
00093
00094 static void
00095 gen_poly()
00096
00097
00098
00099
00100
00101
00102
00103
00104 {
00105 register int ii, jj, ll, kaux;
00106 register int test, aux, nocycles, root, noterms, rdncy;
00107 int cycle[1024][21], size[1024], min[1024], zeros[1024];
00108
00109
00110 cycle[0][0] = 0;
00111 size[0] = 1;
00112 cycle[1][0] = 1;
00113 size[1] = 1;
00114 jj = 1;
00115 if (m > 9) {
00116 printf("BCH: gen_poly() - Computing cycle sets modulo %d\n", n);
00117 }
00118 do {
00119
00120 ii = 0;
00121 do {
00122 ii++;
00123 cycle[jj][ii] = (cycle[jj][ii - 1] * 2) % n;
00124 size[jj]++;
00125 aux = (cycle[jj][ii] * 2) % n;
00126 } while (aux != cycle[jj][0]);
00127
00128 ll = 0;
00129 do {
00130 ll++;
00131 test = 0;
00132 for (ii = 1; ((ii <= jj) && (!test)); ii++)
00133
00134 for (kaux = 0; ((kaux < size[ii]) && (!test)); kaux++)
00135 if (ll == cycle[ii][kaux])
00136 test = 1;
00137 } while ((test) && (ll < (n - 1)));
00138 if (!(test)) {
00139 jj++;
00140 cycle[jj][0] = ll;
00141 size[jj] = 1;
00142 }
00143 } while (ll < (n - 1));
00144 nocycles = jj;
00145
00146 d = 2 * t + 1;
00147
00148 kaux = 0;
00149 rdncy = 0;
00150 for (ii = 1; ii <= nocycles; ii++) {
00151 min[kaux] = 0;
00152 test = 0;
00153 for (jj = 0; ((jj < size[ii]) && (!test)); jj++)
00154 for (root = 1; ((root < d) && (!test)); root++)
00155 if (root == cycle[ii][jj]) {
00156 test = 1;
00157 min[kaux] = ii;
00158 }
00159 if (min[kaux]) {
00160 rdncy += size[min[kaux]];
00161 kaux++;
00162 }
00163 }
00164 noterms = kaux;
00165 kaux = 1;
00166 for (ii = 0; ii < noterms; ii++)
00167 for (jj = 0; jj < size[min[ii]]; jj++) {
00168 zeros[kaux] = cycle[min[ii]][jj];
00169 kaux++;
00170 }
00171 k = length - rdncy;
00172
00173
00174 g[0] = alpha_to[zeros[1]];
00175 g[1] = 1;
00176 for (ii = 2; ii <= rdncy; ii++) {
00177 g[ii] = 1;
00178 for (jj = ii - 1; jj > 0; jj--)
00179 if (g[jj] != 0)
00180 g[jj] = g[jj - 1] ^ alpha_to[(index_of[g[jj]] + zeros[ii]) % n];
00181 else
00182 g[jj] = g[jj - 1];
00183 g[0] = alpha_to[(index_of[g[0]] + zeros[ii]) % n];
00184 }
00185
00186 if (debug >= 5) {
00187 printf("BCH: gen_poly() - g(x) = ");
00188 for (ii = 0; ii <= rdncy; ii++) {
00189 printf("%d", g[ii]);
00190 if (ii && ((ii % 50) == 0))
00191 printf("\n");
00192 }
00193 printf("\n");
00194 }
00195 }
00196
00197
00198 static void
00199 mencode_bch()
00200
00201
00202
00203
00204
00205 {
00206 register int i, j;
00207 register int feedback;
00208
00209 for (i = 0; i < length - k; i++)
00210 bb[i] = 0;
00211 for (i = k - 1; i >= 0; i--) {
00212 feedback = data[i] ^ bb[length - k - 1];
00213 if (feedback != 0) {
00214 for (j = length - k - 1; j > 0; j--)
00215 if (g[j] != 0)
00216 bb[j] = bb[j - 1] ^ feedback;
00217 else
00218 bb[j] = bb[j - 1];
00219 bb[0] = g[0] && feedback;
00220 } else {
00221 for (j = length - k - 1; j > 0; j--)
00222 bb[j] = bb[j - 1];
00223 bb[0] = 0;
00224 }
00225 }
00226 }
00227
00228
00229 static int mdecode_bch(int correction)
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 {
00253 register int i, j, u, q, t2, count = 0, syn_error = 0;
00254 int elp[1026][1024], d[1026], l[1026], u_lu[1026], s[1025];
00255 int root[200], loc[200], err[1024], reg[201];
00256 int returnval = 1;
00257
00258 t2 = 2 * t;
00259
00260
00261 if (debug >= 3) {
00262 printf("BCH: mdecode_bch() - S(x) = ");
00263 }
00264
00265 for (i = 1; i <= t2; i++) {
00266 s[i] = 0;
00267 for (j = 0; j < length; j++)
00268 if (recd[j] != 0)
00269 s[i] ^= alpha_to[(i * j) % n];
00270 if (s[i] != 0) {
00271 syn_error = 1;
00272
00273 if (!correction)
00274 return 0;
00275 }
00276
00277
00278
00279
00280
00281 s[i] = index_of[s[i]];
00282 if (debug >= 3) {
00283 printf("%3d ", s[i]);
00284 }
00285 }
00286 if (debug >= 3) {
00287 printf("\n");
00288 }
00289
00290 if (syn_error) {
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 d[0] = 0;
00302 d[1] = s[1];
00303 elp[0][0] = 0;
00304 elp[1][0] = 1;
00305 for (i = 1; i < t2; i++) {
00306 elp[0][i] = -1;
00307 elp[1][i] = 0;
00308 }
00309 l[0] = 0;
00310 l[1] = 0;
00311 u_lu[0] = -1;
00312 u_lu[1] = 0;
00313 u = 0;
00314
00315 do {
00316 u++;
00317 if (d[u] == -1) {
00318 l[u + 1] = l[u];
00319 for (i = 0; i <= l[u]; i++) {
00320 elp[u + 1][i] = elp[u][i];
00321 elp[u][i] = index_of[elp[u][i]];
00322 }
00323 } else
00324
00325
00326
00327
00328 {
00329 q = u - 1;
00330 while ((d[q] == -1) && (q > 0))
00331 q--;
00332
00333 if (q > 0) {
00334 j = q;
00335 do {
00336 j--;
00337 if ((d[j] != -1) && (u_lu[q] < u_lu[j]))
00338 q = j;
00339 } while (j > 0);
00340 }
00341
00342
00343
00344
00345
00346
00347 if (l[u] > l[q] + u - q)
00348 l[u + 1] = l[u];
00349 else
00350 l[u + 1] = l[q] + u - q;
00351
00352
00353 for (i = 0; i < t2; i++)
00354 elp[u + 1][i] = 0;
00355 for (i = 0; i <= l[q]; i++)
00356 if (elp[q][i] != -1)
00357 elp[u + 1][i + u - q] =
00358 alpha_to[(d[u] + n - d[q] + elp[q][i]) % n];
00359 for (i = 0; i <= l[u]; i++) {
00360 elp[u + 1][i] ^= elp[u][i];
00361 elp[u][i] = index_of[elp[u][i]];
00362 }
00363 }
00364 u_lu[u + 1] = u - l[u + 1];
00365
00366
00367 if (u < t2) {
00368
00369 if (s[u + 1] != -1)
00370 d[u + 1] = alpha_to[s[u + 1]];
00371 else
00372 d[u + 1] = 0;
00373 for (i = 1; i <= l[u + 1]; i++)
00374 if ((s[u + 1 - i] != -1) && (elp[u + 1][i] != 0))
00375 d[u + 1] ^= alpha_to[(s[u + 1 - i]
00376 + index_of[elp[u + 1][i]]) % n];
00377
00378 d[u + 1] = index_of[d[u + 1]];
00379 }
00380 } while ((u < t2) && (l[u + 1] <= t));
00381
00382 u++;
00383 if (l[u] <= t) {
00384
00385 for (i = 0; i <= l[u]; i++)
00386 elp[u][i] = index_of[elp[u][i]];
00387
00388 if (debug >= 5) {
00389 printf("BCH: mencode_bch() - sigma(x) = ");
00390 for (i = 0; i <= l[u]; i++)
00391 printf("%3d ", elp[u][i]);
00392 printf("\n");
00393 }
00394
00395 if (debug >= 3) {
00396 printf("BCH: mencode_bch() - Roots: ");
00397 }
00398
00399 for (i = 1; i <= l[u]; i++)
00400 reg[i] = elp[u][i];
00401 count = 0;
00402 for (i = 1; i <= n; i++) {
00403 q = 1;
00404 for (j = 1; j <= l[u]; j++)
00405 if (reg[j] != -1) {
00406 reg[j] = (reg[j] + j) % n;
00407 q ^= alpha_to[reg[j]];
00408 }
00409 if (!q) {
00410
00411 root[count] = i;
00412 loc[count] = n - i;
00413 count++;
00414 if (debug >=3 )
00415 printf("%3d ", n - i);
00416 }
00417 }
00418 if (debug >= 3)
00419 printf("\n");
00420 if (count == l[u]) {
00421
00422 for (i = 0; i < l[u]; i++)
00423 recd[loc[i]] ^= 1;
00424 }
00425 else{
00426 if (debug >=3)
00427 printf("mdecode_bch() - Incomplete decoding: errors detected\n");
00428 }
00429 }
00430 }
00431 return returnval;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441 static void bch_init(bch_type type)
00442 {
00443 static bch_type old_type=-1;
00444 int i,j;
00445
00446
00447
00448
00449
00450
00451 if (old_type != type) {
00452
00453
00454
00455 for (i=0;i<21;i++)
00456 p[i] = 0;
00457
00458
00459
00460
00461 switch(type) {
00462 case BCH15_5:
00463
00464 k=5; t=3; m = 4; length = 15;
00465 break;
00466 case BCH15_7:
00467
00468 k=7; t=2; m = 4; length = 15;
00469 break;
00470 case BCH15_11:
00471
00472 k=11; t=1; m = 4; length = 15;
00473 break;
00474 case BCH31_6:
00475
00476 k=6; t=7; m = 5; length = 31;
00477 break;
00478 case BCH31_11:
00479
00480 k=11; t=5; m = 5; length = 31;
00481 break;
00482 case BCH63_7:
00483
00484 k=7; t=15; m = 6; length = 63;
00485 break;
00486 case BCH63_10:
00487
00488 k=10; t=13; m = 6; length = 63;
00489 break;
00490 }
00491
00492
00493
00494
00495 n=1;
00496 for (i=0;i<m;i++)
00497 n*=2;
00498 n-=1;
00499
00500
00501
00502
00503 switch(type) {
00504 case BCH15_5:
00505 case BCH15_7:
00506 case BCH15_11:
00507
00508 p[0]=1; p[1]=1; p[4]=1;
00509 break;
00510 case BCH31_6:
00511 case BCH31_11:
00512
00513 p[0]=1; p[2]=1; p[5]=1;
00514 break;
00515 case BCH63_7:
00516 case BCH63_10:
00517
00518 p[0]=1; p[1]=1; p[6]=1;
00519 break;
00520 }
00521 generate_gf();
00522 gen_poly();
00523 }
00524 }
00525
00526
00527
00528
00529 void encode_bch(unsigned long bits, byte *block, bch_type type)
00530
00531
00532
00533 {
00534 int i,j;
00535
00536 if (debug >= 3) {
00537 printf("BCH: encode_bch() type = %s\n", bch_type_str(type));
00538 }
00539
00540 if (type == BCHNONE) {
00541 block[0] = bits & 0xFF;
00542 return;
00543 }
00544
00545
00546
00547
00548 bch_init(type);
00549
00550
00551
00552
00553
00554 for (i=0;i<k;i++)
00555 data[i] = getbitint(bits,(16-i));
00556
00557
00558
00559
00560 mencode_bch();
00561
00562
00563
00564
00565 for (i = 0; i < length - k; i++)
00566 recd[i] = bb[i];
00567 for (i = 0; i < k; i++)
00568 recd[i + length - k] = data[i];
00569
00570
00571
00572
00573 for (i=0;i<=(length/8);i++)
00574 for(j=1;j<=8;j++)
00575 setbit(&(block[i]),j,recd[(8*i)+j-1]);
00576
00577 }
00578
00579
00580 int decode_bch(unsigned long *bits, byte *block, bch_type type, int correction)
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 {
00594 int i, j;
00595 unsigned int r=0;
00596 int returnval=0;
00597
00598
00599 if ((correction!=0)&&(correction!=1))
00600 error("decode_bch","incorrect correction mode");
00601
00602
00603
00604
00605 if (debug >= 3) {
00606 printf("BCH: decode_bch() - bch_code = %s\n", bch_type_str(type));
00607 }
00608
00609 if (type == BCHNONE) {
00610 *bits = block[0];
00611 return 1;
00612 }
00613
00614
00615
00616
00617 bch_init(type);
00618
00619
00620
00621
00622
00623
00624 for (i=0;i<m-1;i++)
00625 for (j=1;j<8;j++)
00626 recd[(8*i)+j-1] = getbit(block[i],j);
00627
00628
00629
00630
00631 returnval = mdecode_bch(correction);
00632
00633
00634
00635
00636
00637 j=1;
00638 r = 0;
00639 for (i=length-k;i<length;i++) {
00640 r += j*recd[i];
00641 j*=2;
00642 }
00643 *bits = r;
00644
00645 if (debug >= 3) {
00646 printf("BCH: decode_bch() bits = %d\n", *bits);
00647 }
00648
00649 return (returnval);
00650 }
00651
00652
00653
00654
00655 bch_type strtobch_type(char *str)
00656 {
00657 int i;
00658 i=strlen(str)-1;
00659 while (i > 0 && (str[i]==' ' || str[i]=='\t'))
00660 str[i]=0;
00661
00662 if (equals(str, "BCH15_5"))
00663 return BCH15_5;
00664 else if (equals(str, "BCH15_7"))
00665 return BCH15_7;
00666 else if (equals(str, "BCH15_11"))
00667 return BCH15_11;
00668 else if (equals(str, "BCH31_6"))
00669 return BCH31_6;
00670 else if (equals(str, "BCH31_11"))
00671 return BCH31_11;
00672 else if (equals(str, "BCH63_7"))
00673 return BCH63_7;
00674 else if (equals(str, "BCH63_10"))
00675 return BCH63_10;
00676 else if (equals(str, "GOLAY23_12"))
00677 return GOLAY23_12;
00678 else
00679 return BCHNONE;
00680 }
00681
00682 char *bch_type_str(bch_type type)
00683 {
00684 switch(type) {
00685 case BCHNONE: return "None";
00686 case BCH15_5: return "(15,5)";
00687 case BCH15_7: return "(15,7)";
00688 case BCH15_11: return "(15,11)";
00689 case BCH31_6: return "(31,6)";
00690 case BCH31_11: return "(31,11)";
00691 case BCH63_7: return "(63,7)";
00692 case BCH63_10: return "(63,10)";
00693 }
00694 }
00695
00696
00697 int code_length(bch_type b)
00698 {
00699 switch(b)
00700 {
00701 case BCHNONE:
00702 return 7;
00703 case BCH15_5:
00704 case BCH15_7:
00705 case BCH15_11:
00706 return 15;
00707 case BCH31_6:
00708 case BCH31_11:
00709 return 31;
00710 case BCH63_7:
00711 case BCH63_10:
00712 return 63;
00713 case GOLAY23_12:
00714 return 23;
00715 }
00716 return 0;
00717 }
00718
00719
00720 int info_length(bch_type b)
00721 {
00722 switch(b)
00723 {
00724 case BCHNONE: return 8;
00725 case BCH15_5: return 5;
00726 case BCH15_7: return 7;
00727 case BCH15_11: return 11;
00728 case BCH31_6: return 6;
00729 case BCH31_11: return 11;
00730 case BCH63_7: return 7;
00731 case BCH63_10: return 10;
00732 }
00733 return 0;
00734 }