28 static void encode(
const uint8_t* msg,
int len,
int ecc, uint8_t* out,
31 LOGE(
"RSCodec: invalid length %d + %d", len, ecc);
37 memcpy(work, msg, len);
38 memset(work + len, 0, ecc);
40 for (
int i = 0; i < len; i++) {
41 uint8_t coef = work[i];
42 if (coef == 0)
continue;
43 for (
int j = 1; j <= ecc; j++) work[i + j] ^=
mul(gen[j], coef);
45 memcpy(out, msg, len);
46 memcpy(out + len, work + len, ecc);
51 static bool decode(uint8_t* data,
int len,
int ecc,
int fcr = 0) {
52 return correct(data, len, ecc, fcr) >= 0;
58 static int correct(uint8_t* data,
int len,
int ecc,
int fcr = 0) {
62 if (!
syndromes(data, n, ecc, synd, fcr))
return 0;
67 int nlambda = 1, nprev = 1, L = 0, m = 1;
69 for (
int r = 0; r < ecc; r++) {
71 for (
int i = 1; i <= L && i < nlambda; i++)
72 d ^=
mul(lambda[i], synd[r - i]);
77 uint8_t coef =
div(d, b);
78 bool grow = 2 * L <= r;
80 memcpy(tmp, lambda, nlambda);
84 if (nprev + m > nlambda) {
85 memset(lambda + nlambda, 0, nprev + m - nlambda);
88 for (
int i = 0; i < nprev; i++) lambda[i + m] ^=
mul(coef, prev[i]);
91 memcpy(prev, tmp, ntmp);
99 if (2 * L > ecc)
return -1;
104 for (
int i = 0; i < n; i++) {
105 int power = n - 1 - i;
106 uint8_t x_inv =
pow2(255 - power);
107 if (
eval(lambda, nlambda, x_inv) == 0) {
108 if (nerr == L)
return -1;
112 if (nerr != L)
return -1;
116 for (
int i = 0; i < ecc; i++) {
118 for (
int j = 0; j <= i && j < nlambda; j++)
119 v ^=
mul(lambda[j], synd[i - j]);
122 for (
int k = 0; k < nerr; k++) {
123 int power = n - 1 - pos[k];
124 uint8_t x =
pow2(power);
125 uint8_t x_inv =
pow2(255 - power);
128 for (
int i = 1; i < nlambda; i += 2)
129 deriv ^=
mul(lambda[i],
powOf(x_inv, i - 1));
130 if (deriv == 0)
return -1;
132 uint8_t factor =
pow2(((1 - fcr) * power % 255 + 255) % 255);
133 uint8_t e =
mul(factor,
div(
eval(omega, ecc, x_inv), deriv));
137 return syndromes(data, n, ecc, synd, fcr) ? -1 : nerr;
146 for (
int i = 0; i < 255; i++) {
150 if (x & 0x100) x ^= 0x11d;
152 for (
int i = 255; i < 512; i++)
exp[i] =
exp[i - 255];
162 static uint8_t
mul(uint8_t a, uint8_t b) {
163 if (a == 0 || b == 0)
return 0;
168 static uint8_t
div(uint8_t a, uint8_t b) {
169 if (a == 0)
return 0;
171 return t.
exp[(t.
log[a] + 255 - t.
log[b]) % 255];
177 static uint8_t
powOf(uint8_t x,
int power) {
178 if (power == 0)
return 1;
179 if (x == 0)
return 0;
181 return t.
exp[(t.
log[x] * power) % 255];
185 static uint8_t
eval(
const uint8_t* poly,
int n, uint8_t x) {
187 for (
int i = n - 1; i >= 0; i--) y =
mul(y, x) ^ poly[i];
195 for (
int i = 0; i < ecc; i++) {
197 uint8_t root =
pow2(fcr + i);
199 for (
int j = len; j > 0; j--) gen[j] ^=
mul(gen[j - 1], root);
206 static bool syndromes(
const uint8_t* data,
int n,
int ecc, uint8_t* synd,
209 for (
int j = 0; j < ecc; j++) {
210 uint8_t x =
pow2(fcr + j);
212 for (
int i = 0; i < n; i++) y =
mul(y, x) ^ data[i];
214 if (y != 0) errors =
true;
Reed-Solomon code over GF(256) with the polynomial 0x11d and lengths which are defined at runtime....
Definition ReedSolomon.h:18
static bool syndromes(const uint8_t *data, int n, int ecc, uint8_t *synd, int fcr)
Definition ReedSolomon.h:206
static void encode(const uint8_t *msg, int len, int ecc, uint8_t *out, int fcr=0)
Definition ReedSolomon.h:28
static const Tables & tables()
Definition ReedSolomon.h:157
static uint8_t eval(const uint8_t *poly, int n, uint8_t x)
Evaluates a polynomial with ascending powers.
Definition ReedSolomon.h:185
static uint8_t div(uint8_t a, uint8_t b)
Definition ReedSolomon.h:168
static constexpr int MAX_ECC
Definition ReedSolomon.h:24
static constexpr int MAX_LEN
max length of message + parity
Definition ReedSolomon.h:21
static uint8_t powOf(uint8_t x, int power)
Definition ReedSolomon.h:177
static uint8_t mul(uint8_t a, uint8_t b)
Definition ReedSolomon.h:162
static uint8_t pow2(int power)
alpha^power (power 0 - 255)
Definition ReedSolomon.h:175
static void generator(int ecc, uint8_t *gen, int fcr)
Generator polynomial (descending powers) with ecc + 1 coefficients.
Definition ReedSolomon.h:192
static bool decode(uint8_t *data, int len, int ecc, int fcr=0)
Definition ReedSolomon.h:51
static int correct(uint8_t *data, int len, int ecc, int fcr=0)
Definition ReedSolomon.h:58
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
Definition ReedSolomon.h:141
uint8_t exp[512]
Definition ReedSolomon.h:142
Tables()
Definition ReedSolomon.h:144
uint8_t log[256]
Definition ReedSolomon.h:143