mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-06-25 15:20:31 -04:00
Formatted code (#1007)
* Updated style * Updated files * fixed new line * Updated spacing * File fix WIP * Updated to clang 13 * updated comment style * Removed old comment code
This commit is contained in:
parent
7aca7ce74d
commit
033c4e9a5b
599 changed files with 70746 additions and 66896 deletions
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* BCH Encoder/Decoder - Adapted from GNURadio
|
||||
*
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -29,280 +29,264 @@
|
|||
#include "bch_code.hpp"
|
||||
|
||||
void BCHCode::generate_gf() {
|
||||
/*
|
||||
* generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m]
|
||||
* lookup tables: index->polynomial form alpha_to[] contains j=alpha**i;
|
||||
* polynomial form -> index form index_of[j=alpha**i] = i alpha=2 is the
|
||||
* primitive element of GF(2**m)
|
||||
*/
|
||||
|
||||
int i, mask;
|
||||
mask = 1;
|
||||
alpha_to[m] = 0;
|
||||
|
||||
for (i = 0; i < m; i++)
|
||||
{
|
||||
alpha_to[i] = mask;
|
||||
|
||||
index_of[alpha_to[i]] = i;
|
||||
|
||||
if (p[i] != 0)
|
||||
alpha_to[m] ^= mask;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
/*
|
||||
* generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m]
|
||||
* lookup tables: index->polynomial form alpha_to[] contains j=alpha**i;
|
||||
* polynomial form -> index form index_of[j=alpha**i] = i alpha=2 is the
|
||||
* primitive element of GF(2**m)
|
||||
*/
|
||||
|
||||
index_of[alpha_to[m]] = m;
|
||||
|
||||
mask >>= 1;
|
||||
|
||||
for (i = m + 1; i < n; i++)
|
||||
{
|
||||
if (alpha_to[i - 1] >= mask)
|
||||
alpha_to[i] = alpha_to[m] ^ ((alpha_to[i - 1] ^ mask) << 1);
|
||||
else
|
||||
alpha_to[i] = alpha_to[i - 1] << 1;
|
||||
|
||||
index_of[alpha_to[i]] = i;
|
||||
}
|
||||
|
||||
index_of[0] = -1;
|
||||
int i, mask;
|
||||
mask = 1;
|
||||
alpha_to[m] = 0;
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
alpha_to[i] = mask;
|
||||
|
||||
index_of[alpha_to[i]] = i;
|
||||
|
||||
if (p[i] != 0)
|
||||
alpha_to[m] ^= mask;
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
index_of[alpha_to[m]] = m;
|
||||
|
||||
mask >>= 1;
|
||||
|
||||
for (i = m + 1; i < n; i++) {
|
||||
if (alpha_to[i - 1] >= mask)
|
||||
alpha_to[i] = alpha_to[m] ^ ((alpha_to[i - 1] ^ mask) << 1);
|
||||
else
|
||||
alpha_to[i] = alpha_to[i - 1] << 1;
|
||||
|
||||
index_of[alpha_to[i]] = i;
|
||||
}
|
||||
|
||||
index_of[0] = -1;
|
||||
}
|
||||
|
||||
|
||||
void BCHCode::gen_poly() {
|
||||
/*
|
||||
* Compute generator polynomial of BCH code of length = 31, redundancy = 10
|
||||
* (OK, this is not very efficient, but we only do it once, right? :)
|
||||
*/
|
||||
/*
|
||||
* Compute generator polynomial of BCH code of length = 31, redundancy = 10
|
||||
* (OK, this is not very efficient, but we only do it once, right? :)
|
||||
*/
|
||||
|
||||
int ii, jj, ll, kaux;
|
||||
int test, aux, nocycles, root, noterms, rdncy;
|
||||
int cycle[15][6], size[15], min[11], zeros[11];
|
||||
|
||||
// Generate cycle sets modulo 31
|
||||
cycle[0][0] = 0; size[0] = 1;
|
||||
cycle[1][0] = 1; size[1] = 1;
|
||||
jj = 1; // cycle set index
|
||||
|
||||
do
|
||||
{
|
||||
// Generate the jj-th cycle set
|
||||
ii = 0;
|
||||
do
|
||||
{
|
||||
ii++;
|
||||
cycle[jj][ii] = (cycle[jj][ii - 1] * 2) % n;
|
||||
size[jj]++;
|
||||
aux = (cycle[jj][ii] * 2) % n;
|
||||
int ii, jj, ll, kaux;
|
||||
int test, aux, nocycles, root, noterms, rdncy;
|
||||
int cycle[15][6], size[15], min[11], zeros[11];
|
||||
|
||||
} while (aux != cycle[jj][0]);
|
||||
|
||||
// Next cycle set representative
|
||||
ll = 0;
|
||||
do
|
||||
{
|
||||
ll++;
|
||||
test = 0;
|
||||
for (ii = 1; ((ii <= jj) && (!test)); ii++)
|
||||
// Examine previous cycle sets
|
||||
for (kaux = 0; ((kaux < size[ii]) && (!test)); kaux++)
|
||||
if (ll == cycle[ii][kaux])
|
||||
test = 1;
|
||||
}
|
||||
while ((test) && (ll < (n - 1)));
|
||||
|
||||
if (!(test))
|
||||
{
|
||||
jj++; // next cycle set index
|
||||
cycle[jj][0] = ll;
|
||||
size[jj] = 1;
|
||||
}
|
||||
// Generate cycle sets modulo 31
|
||||
cycle[0][0] = 0;
|
||||
size[0] = 1;
|
||||
cycle[1][0] = 1;
|
||||
size[1] = 1;
|
||||
jj = 1; // cycle set index
|
||||
|
||||
} while (ll < (n - 1));
|
||||
|
||||
nocycles = jj; // number of cycle sets modulo n
|
||||
// Search for roots 1, 2, ..., d-1 in cycle sets
|
||||
|
||||
kaux = 0;
|
||||
rdncy = 0;
|
||||
|
||||
for (ii = 1; ii <= nocycles; ii++)
|
||||
{
|
||||
min[kaux] = 0;
|
||||
|
||||
for (jj = 0; jj < size[ii]; jj++)
|
||||
for (root = 1; root < d; root++)
|
||||
if (root == cycle[ii][jj])
|
||||
min[kaux] = ii;
|
||||
|
||||
if (min[kaux])
|
||||
{
|
||||
rdncy += size[min[kaux]];
|
||||
kaux++;
|
||||
}
|
||||
}
|
||||
do {
|
||||
// Generate the jj-th cycle set
|
||||
ii = 0;
|
||||
do {
|
||||
ii++;
|
||||
cycle[jj][ii] = (cycle[jj][ii - 1] * 2) % n;
|
||||
size[jj]++;
|
||||
aux = (cycle[jj][ii] * 2) % n;
|
||||
|
||||
noterms = kaux;
|
||||
kaux = 1;
|
||||
|
||||
for (ii = 0; ii < noterms; ii++)
|
||||
for (jj = 0; jj < size[min[ii]]; jj++)
|
||||
{
|
||||
zeros[kaux] = cycle[min[ii]][jj];
|
||||
kaux++;
|
||||
}
|
||||
|
||||
// Compute generator polynomial
|
||||
g[0] = alpha_to[zeros[1]];
|
||||
g[1] = 1; // g(x) = (X + zeros[1]) initially
|
||||
|
||||
for (ii = 2; ii <= rdncy; ii++)
|
||||
{
|
||||
g[ii] = 1;
|
||||
for (jj = ii - 1; jj > 0; jj--)
|
||||
if (g[jj] != 0)
|
||||
g[jj] = g[jj - 1] ^ alpha_to[(index_of[g[jj]] + zeros[ii]) % n];
|
||||
else
|
||||
g[jj] = g[jj - 1];
|
||||
|
||||
g[0] = alpha_to[(index_of[g[0]] + zeros[ii]) % n];
|
||||
}
|
||||
} while (aux != cycle[jj][0]);
|
||||
|
||||
// Next cycle set representative
|
||||
ll = 0;
|
||||
do {
|
||||
ll++;
|
||||
test = 0;
|
||||
for (ii = 1; ((ii <= jj) && (!test)); ii++)
|
||||
// Examine previous cycle sets
|
||||
for (kaux = 0; ((kaux < size[ii]) && (!test)); kaux++)
|
||||
if (ll == cycle[ii][kaux])
|
||||
test = 1;
|
||||
} while ((test) && (ll < (n - 1)));
|
||||
|
||||
if (!(test)) {
|
||||
jj++; // next cycle set index
|
||||
cycle[jj][0] = ll;
|
||||
size[jj] = 1;
|
||||
}
|
||||
|
||||
} while (ll < (n - 1));
|
||||
|
||||
nocycles = jj; // number of cycle sets modulo n
|
||||
// Search for roots 1, 2, ..., d-1 in cycle sets
|
||||
|
||||
kaux = 0;
|
||||
rdncy = 0;
|
||||
|
||||
for (ii = 1; ii <= nocycles; ii++) {
|
||||
min[kaux] = 0;
|
||||
|
||||
for (jj = 0; jj < size[ii]; jj++)
|
||||
for (root = 1; root < d; root++)
|
||||
if (root == cycle[ii][jj])
|
||||
min[kaux] = ii;
|
||||
|
||||
if (min[kaux]) {
|
||||
rdncy += size[min[kaux]];
|
||||
kaux++;
|
||||
}
|
||||
}
|
||||
|
||||
noterms = kaux;
|
||||
kaux = 1;
|
||||
|
||||
for (ii = 0; ii < noterms; ii++)
|
||||
for (jj = 0; jj < size[min[ii]]; jj++) {
|
||||
zeros[kaux] = cycle[min[ii]][jj];
|
||||
kaux++;
|
||||
}
|
||||
|
||||
// Compute generator polynomial
|
||||
g[0] = alpha_to[zeros[1]];
|
||||
g[1] = 1; // g(x) = (X + zeros[1]) initially
|
||||
|
||||
for (ii = 2; ii <= rdncy; ii++) {
|
||||
g[ii] = 1;
|
||||
for (jj = ii - 1; jj > 0; jj--)
|
||||
if (g[jj] != 0)
|
||||
g[jj] = g[jj - 1] ^ alpha_to[(index_of[g[jj]] + zeros[ii]) % n];
|
||||
else
|
||||
g[jj] = g[jj - 1];
|
||||
|
||||
g[0] = alpha_to[(index_of[g[0]] + zeros[ii]) % n];
|
||||
}
|
||||
}
|
||||
|
||||
int * BCHCode::encode(int data[]) {
|
||||
// Calculate redundant bits bb[]
|
||||
int* BCHCode::encode(int data[]) {
|
||||
// Calculate redundant bits bb[]
|
||||
|
||||
int h, i, j=0, start=0, end=(n-k); // 10
|
||||
int Mr[31];
|
||||
|
||||
if (!valid) return nullptr;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
Mr[i] = 0;
|
||||
}
|
||||
|
||||
for (h = 0; h < k; ++h)
|
||||
Mr[h] = data[h];
|
||||
|
||||
while (end < n)
|
||||
{
|
||||
for (i=end; i>start-2; --i)
|
||||
{
|
||||
if (Mr[start] != 0)
|
||||
{
|
||||
Mr[i]^=g[j];
|
||||
++j;
|
||||
}
|
||||
else
|
||||
{
|
||||
++start;
|
||||
j = 0;
|
||||
end = start+(n-k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = start; i<end; ++i) {
|
||||
bb[j]=Mr[i];
|
||||
++j;
|
||||
}
|
||||
|
||||
return bb;
|
||||
int h, i, j = 0, start = 0, end = (n - k); // 10
|
||||
int Mr[31];
|
||||
|
||||
if (!valid) return nullptr;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
Mr[i] = 0;
|
||||
}
|
||||
|
||||
for (h = 0; h < k; ++h)
|
||||
Mr[h] = data[h];
|
||||
|
||||
while (end < n) {
|
||||
for (i = end; i > start - 2; --i) {
|
||||
if (Mr[start] != 0) {
|
||||
Mr[i] ^= g[j];
|
||||
++j;
|
||||
} else {
|
||||
++start;
|
||||
j = 0;
|
||||
end = start + (n - k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = start; i < end; ++i) {
|
||||
bb[j] = Mr[i];
|
||||
++j;
|
||||
}
|
||||
|
||||
return bb;
|
||||
};
|
||||
|
||||
|
||||
int BCHCode::decode(int recd[]) {
|
||||
// We do not need the Berlekamp algorithm to decode.
|
||||
// We solve before hand two equations in two variables.
|
||||
// We do not need the Berlekamp algorithm to decode.
|
||||
// We solve before hand two equations in two variables.
|
||||
|
||||
int i, j, q;
|
||||
int elp[3], s[5], s3;
|
||||
int count = 0, syn_error = 0;
|
||||
int loc[3], reg[3];
|
||||
int aux;
|
||||
int retval=0;
|
||||
|
||||
if (!valid) return 0;
|
||||
|
||||
for (i = 1; i <= 4; i++) {
|
||||
s[i] = 0;
|
||||
for (j = 0; j < n; j++) {
|
||||
if (recd[j] != 0) {
|
||||
s[i] ^= alpha_to[(i * j) % n];
|
||||
}
|
||||
}
|
||||
if (s[i] != 0) {
|
||||
syn_error = 1; // set flag if non-zero syndrome
|
||||
}
|
||||
/* NOTE: If only error detection is needed,
|
||||
* then exit the program here...
|
||||
*/
|
||||
// Convert syndrome from polynomial form to index form
|
||||
s[i] = index_of[s[i]];
|
||||
};
|
||||
|
||||
if (syn_error) { // If there are errors, try to correct them
|
||||
if (s[1] != -1) {
|
||||
s3 = (s[1] * 3) % n;
|
||||
if ( s[3] == s3 ) { // Was it a single error ?
|
||||
//printf("One error at %d\n", s[1]);
|
||||
recd[s[1]] ^= 1; // Yes: Correct it
|
||||
} else {
|
||||
/* Assume two errors occurred and solve
|
||||
* for the coefficients of sigma(x), the
|
||||
* error locator polynomial
|
||||
*/
|
||||
if (s[3] != -1) {
|
||||
aux = alpha_to[s3] ^ alpha_to[s[3]];
|
||||
} else {
|
||||
aux = alpha_to[s3];
|
||||
}
|
||||
elp[0] = 0;
|
||||
elp[1] = (s[2] - index_of[aux] + n) % n;
|
||||
elp[2] = (s[1] - index_of[aux] + n) % n;
|
||||
//printf("sigma(x) = ");
|
||||
//for (i = 0; i <= 2; i++) {
|
||||
// printf("%3d ", elp[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//printf("Roots: ");
|
||||
|
||||
// Find roots of the error location polynomial
|
||||
for (i = 1; i <= 2; i++) {
|
||||
reg[i] = elp[i];
|
||||
}
|
||||
count = 0;
|
||||
for (i = 1; i <= n; i++) { // Chien search
|
||||
q = 1;
|
||||
for (j = 1; j <= 2; j++) {
|
||||
if (reg[j] != -1) {
|
||||
reg[j] = (reg[j] + j) % n;
|
||||
q ^= alpha_to[reg[j]];
|
||||
}
|
||||
}
|
||||
if (!q) { // store error location number indices
|
||||
loc[count] = i % n;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 2) {
|
||||
// no. roots = degree of elp hence 2 errors
|
||||
for (i = 0; i < 2; i++)
|
||||
recd[loc[i]] ^= 1;
|
||||
} else { // Cannot solve: Error detection
|
||||
retval=1;
|
||||
}
|
||||
}
|
||||
} else if (s[2] != -1) { // Error detection
|
||||
retval=1;
|
||||
}
|
||||
}
|
||||
int i, j, q;
|
||||
int elp[3], s[5], s3;
|
||||
int count = 0, syn_error = 0;
|
||||
int loc[3], reg[3];
|
||||
int aux;
|
||||
int retval = 0;
|
||||
|
||||
return retval;
|
||||
if (!valid) return 0;
|
||||
|
||||
for (i = 1; i <= 4; i++) {
|
||||
s[i] = 0;
|
||||
for (j = 0; j < n; j++) {
|
||||
if (recd[j] != 0) {
|
||||
s[i] ^= alpha_to[(i * j) % n];
|
||||
}
|
||||
}
|
||||
if (s[i] != 0) {
|
||||
syn_error = 1; // set flag if non-zero syndrome
|
||||
}
|
||||
/* NOTE: If only error detection is needed,
|
||||
* then exit the program here...
|
||||
*/
|
||||
// Convert syndrome from polynomial form to index form
|
||||
s[i] = index_of[s[i]];
|
||||
};
|
||||
|
||||
if (syn_error) { // If there are errors, try to correct them
|
||||
if (s[1] != -1) {
|
||||
s3 = (s[1] * 3) % n;
|
||||
if (s[3] == s3) { // Was it a single error ?
|
||||
// printf("One error at %d\n", s[1]);
|
||||
recd[s[1]] ^= 1; // Yes: Correct it
|
||||
} else {
|
||||
/* Assume two errors occurred and solve
|
||||
* for the coefficients of sigma(x), the
|
||||
* error locator polynomial
|
||||
*/
|
||||
if (s[3] != -1) {
|
||||
aux = alpha_to[s3] ^ alpha_to[s[3]];
|
||||
} else {
|
||||
aux = alpha_to[s3];
|
||||
}
|
||||
elp[0] = 0;
|
||||
elp[1] = (s[2] - index_of[aux] + n) % n;
|
||||
elp[2] = (s[1] - index_of[aux] + n) % n;
|
||||
// printf("sigma(x) = ");
|
||||
// for (i = 0; i <= 2; i++) {
|
||||
// printf("%3d ", elp[i]);
|
||||
// }
|
||||
// printf("\n");
|
||||
// printf("Roots: ");
|
||||
|
||||
// Find roots of the error location polynomial
|
||||
for (i = 1; i <= 2; i++) {
|
||||
reg[i] = elp[i];
|
||||
}
|
||||
count = 0;
|
||||
for (i = 1; i <= n; i++) { // Chien search
|
||||
q = 1;
|
||||
for (j = 1; j <= 2; j++) {
|
||||
if (reg[j] != -1) {
|
||||
reg[j] = (reg[j] + j) % n;
|
||||
q ^= alpha_to[reg[j]];
|
||||
}
|
||||
}
|
||||
if (!q) { // store error location number indices
|
||||
loc[count] = i % n;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 2) {
|
||||
// no. roots = degree of elp hence 2 errors
|
||||
for (i = 0; i < 2; i++)
|
||||
recd[loc[i]] ^= 1;
|
||||
} else { // Cannot solve: Error detection
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
} else if (s[2] != -1) { // Error detection
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -321,44 +305,48 @@ int BCHCode::decode(int recd[]) {
|
|||
* bb[] = coefficients of redundancy polynomial ( x**(10) i(x) ) modulo g(x)
|
||||
*/
|
||||
BCHCode::BCHCode(
|
||||
std::vector<int> p_init, int m, int n, int k, int t
|
||||
) : m { m },
|
||||
n { n },
|
||||
k { k },
|
||||
t { t } {
|
||||
size_t i;
|
||||
|
||||
d = 5;
|
||||
|
||||
alpha_to = (int *)chHeapAlloc(NULL, sizeof(int) * (n + 1));
|
||||
index_of = (int *)chHeapAlloc(0, sizeof(int) * (n + 1));
|
||||
p = (int *)chHeapAlloc(0, sizeof(int) * (m + 1));
|
||||
g = (int *)chHeapAlloc(0, sizeof(int) * (n - k + 1));
|
||||
bb = (int *)chHeapAlloc(0, sizeof(int) * (n - k + 1));
|
||||
|
||||
if (alpha_to == NULL ||
|
||||
index_of == NULL ||
|
||||
p == NULL ||
|
||||
g == NULL ||
|
||||
bb == NULL)
|
||||
valid = false;
|
||||
else
|
||||
valid = true;
|
||||
|
||||
if (valid) {
|
||||
for (i = 0; i < (size_t)(m + 1); i++) {
|
||||
p[i] = p_init[i];
|
||||
}
|
||||
std::vector<int> p_init,
|
||||
int m,
|
||||
int n,
|
||||
int k,
|
||||
int t)
|
||||
: m{m},
|
||||
n{n},
|
||||
k{k},
|
||||
t{t} {
|
||||
size_t i;
|
||||
|
||||
generate_gf(); /* generate the Galois Field GF(2**m) */
|
||||
gen_poly(); /* Compute the generator polynomial of BCH code */
|
||||
}
|
||||
d = 5;
|
||||
|
||||
alpha_to = (int*)chHeapAlloc(NULL, sizeof(int) * (n + 1));
|
||||
index_of = (int*)chHeapAlloc(0, sizeof(int) * (n + 1));
|
||||
p = (int*)chHeapAlloc(0, sizeof(int) * (m + 1));
|
||||
g = (int*)chHeapAlloc(0, sizeof(int) * (n - k + 1));
|
||||
bb = (int*)chHeapAlloc(0, sizeof(int) * (n - k + 1));
|
||||
|
||||
if (alpha_to == NULL ||
|
||||
index_of == NULL ||
|
||||
p == NULL ||
|
||||
g == NULL ||
|
||||
bb == NULL)
|
||||
valid = false;
|
||||
else
|
||||
valid = true;
|
||||
|
||||
if (valid) {
|
||||
for (i = 0; i < (size_t)(m + 1); i++) {
|
||||
p[i] = p_init[i];
|
||||
}
|
||||
|
||||
generate_gf(); /* generate the Galois Field GF(2**m) */
|
||||
gen_poly(); /* Compute the generator polynomial of BCH code */
|
||||
}
|
||||
}
|
||||
|
||||
BCHCode::~BCHCode() {
|
||||
if (alpha_to != NULL) chHeapFree(alpha_to);
|
||||
if (index_of != NULL) chHeapFree(index_of);
|
||||
if (p != NULL) chHeapFree(p);
|
||||
if (g != NULL) chHeapFree(g);
|
||||
if (bb != NULL) chHeapFree(bb);
|
||||
if (alpha_to != NULL) chHeapFree(alpha_to);
|
||||
if (index_of != NULL) chHeapFree(index_of);
|
||||
if (p != NULL) chHeapFree(p);
|
||||
if (g != NULL) chHeapFree(g);
|
||||
if (bb != NULL) chHeapFree(bb);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue