reed-solomon ecc: GF(16) - RS(15,9) (example)

pull/11/head
Zilog80 2019-02-04 20:20:22 +01:00
rodzic 923e6b17fd
commit 7d8383221e
2 zmienionych plików z 293 dodań i 3 usunięć

Wyświetl plik

@ -104,6 +104,9 @@ static RS_t RS256 = { 255, 12, 24, 231, 0, 1, 1, {0}};
static RS_t RS256ccsds = { 255, 16, 32, 223, 112, 11, 116, {0}};
static RS_t BCH64 = { 63, 2, 12, 51, 1, 1, 1, {0}};
static RS_t RS16_0 = { 15, 3, 6, 9, 0, 1, 1, {0}};
//static RS_t RS16_1 = { 15, 3, 6, 9, 1, 1, 1, {0}};
static GF_t GF;
static RS_t RS;
@ -810,13 +813,38 @@ int rs_init_BCH64() {
return check_gen;
}
int rs_init_RS15() {
int i, check_gen;
ui8_t Xalp[MAX_DEG+1];
GF = GF16RS;
check_gen = GF_genTab( GF, exp_a, log_a);
RS = RS16_0; // N=15, t=3, b=0, p=1
//RS = RS16_1; // N=15, t=3, b=1, p=1
for (i = 0; i <= MAX_DEG; i++) RS.g[i] = 0;
for (i = 0; i <= MAX_DEG; i++) Xalp[i] = 0;
// g(X)=(X-alpha^b)...(X-alpha^(b+2t-1))
RS.g[0] = 0x01;
Xalp[1] = 0x01; // X
for (i = 0; i < 2*RS.t; i++) {
Xalp[0] = exp_a[(RS.b+i) % (GF.ord-1)]; // Xalp[0..1]: X - alpha^(b+i)
poly_mul(RS.g, Xalp, RS.g);
}
return check_gen;
}
int rs_encode(ui8_t cw[]) {
int j;
ui8_t parity[MAX_DEG+1],
ui8_t __cw[MAX_DEG+1],
parity[MAX_DEG+1],
d[MAX_DEG+1];
for (j = 0; j < RS.R; j++) cw[j] = 0;
for (j = 0; j <= MAX_DEG; j++) parity[j] = 0;
poly_divmod(cw, RS.g, d, parity);
for (j = 0; j <= MAX_DEG; j++) __cw[j] = 0;
for (j = RS.R; j < RS.N; j++) __cw[j] = cw[j];
poly_divmod(__cw, RS.g, d, parity);
//if (poly_deg(parity) >= RS.R) return -1;
for (j = 0; j <= poly_deg(parity); j++) cw[j] = parity[j];
return 0;

262
ecc/ecc-rs_gf16.c 100644
Wyświetl plik

@ -0,0 +1,262 @@
/*
GF(2^4) - RS(15,9)
(no bit-packing, i.e. 1 nibble <-> 1 byte)
a)
ka9q-fec:
gcc -c init_rs_char.c
gcc -c encode_rs_char.c
gcc -c decode_rs_char.c
gcc -DKA9Q ecc-rs_gf16.c init_rs_char.o encode_rs_char.o decode_rs_char.o -o ecc-rs15
b)
gcc ecc-rs_gf16.c -o ecc-rs15
*/
#include <stdio.h>
#include <string.h>
#ifdef KA9Q
#include "fec.h"
#endif
typedef unsigned char ui8_t;
typedef unsigned int ui32_t;
#include "bch_ecc.c"
#define BFSIZE 512
#define rs_N 15
#define rs_R 6
#define rs_K (rs_N-rs_R)
ui8_t data[BFSIZE];
ui8_t cw[rs_N+1]; // cw[MAX_DEG+1]; // fixed in encode() ...
ui8_t par[rs_N], msg[rs_N];
int errs;
ui8_t err_pos[rs_R], err_val[rs_R];
#ifdef KA9Q
void *rs;
ui8_t codeword[rs_N];
int errors, errpos[rs_R];
#endif
int main(int argc, char *argv[]) {
int i, l;
int len1, len2;
char *str1 = NULL,
*str2 = NULL;
rs_init_RS15(); // 0x13: X^4 + X + 1
#ifdef KA9Q
rs = init_rs_char( 4, 0x13, 0, 1, 6, 0); // RS16_0
//rs = init_rs_char( 4, 0x13, 1, 1, 6, 0); // RS16_1
#endif
if (argv[0] == NULL) return -1;
for (i = 0; i < BFSIZE; i++) data[i] = 0;
for (i = 0; i < rs_N; i++) cw[i] = 0;
#ifdef KA9Q
for (i = 0; i < rs_N; i++) codeword[i] = 0;
#endif
str1 = argv[1];
len1 = strlen(str1);
if (len1 > BFSIZE) return -1;
for (i = 0; i < len1; i++) {
l = sscanf(str1+i, "%1hhx", data+i); if (l < 1) {/*len1 = i;*/}
}
// 1byte/nibble
for (i = 0; i < rs_K; i++) cw[rs_R+i] = data[i]; // codeword[rs_N-1-i] = cw[i];
for (i = 0; i < rs_N; i++) msg[i] = 0;
for (i = 0; i < rs_N; i++) par[i] = 0;
for (i = 0; i < rs_K; i++) msg[i] = data[rs_K-1-i];
//
// GF(16) %02X -> %1X (1 nibble / 1 byte)
// printf("%1X", cw[i]); // dbg: printf("%02X", cw[i]);
// printf("%1X", cw[i]&0xF); // dbg: printf("%02X", cw[i]);
//
printf("\n");
if (argv[2]) {
str2 = argv[2];
len2 = strlen(str2);
if (len2 > rs_R) len2 = rs_R;
for (i = 0; i < len2; i++) {
l = sscanf(str2+i, "%1hhx", par+i); if (l < 1) {/*len2 = i;*/}
}
while (i < rs_R) par[i++] = 0;
for (i = 0; i < rs_N; i++) cw[i] = 0;
for (i = 0; i < rs_R; i++) cw[i] = par[i];
for (i = 0; i < len1; i++) cw[rs_R+i] = msg[rs_K-1-i];
#ifdef KA9Q
for (i = 0; i < rs_N; i++) codeword[rs_N-1-i] = cw[i];
#endif
printf("msg: ");
for (i = rs_R; i < rs_N; i++) printf("%1X", cw[i]); // dbg: printf("%02X", cw[i]);
printf("\n");
printf("par: ");
for (i = 0; i < rs_R; i++) printf("%1X", cw[i]); printf("\n");
printf("\n");
printf("cw\n");
errs = rs_decode(cw, err_pos, err_val);
printf("errs: %d\n", errs);
if (errs > 0) {
printf("pos: ");
for (i = 0; i < errs; i++) printf(" %d", err_pos[i]);
printf("\n");
}
for (i = 0; i < rs_N; i++) printf("%1X", cw[i]); printf("\n");
#ifdef KA9Q
printf("\n");
printf("codeword\n");
errors = decode_rs_char(rs, codeword, errpos, 0);
printf("errors: %d\n", errors);
if (errors > 0) {
printf("pos: ");
for (i = 0; i < errors; i++) printf(" %d", errpos[i]);
printf("\n");
}
for (i = 0; i < rs_N; i++) printf("%1X", codeword[i]); printf("\n");
#endif
} else {
printf("msg: ");
for (i = rs_R; i < rs_N; i++) printf("%1X", cw[i]); // dbg: printf("%02X", cw[i]);
printf("\n");
printf("\n");
printf("cw\n");
rs_encode(cw);
printf("par: ");
for (i = 0; i < rs_R; i++) printf("%1X", cw[i]); printf("\n");
printf("cw-enc:\n");
for (i = 0; i < rs_N; i++) {
//if (i == rs_R) printf(" ");
printf("%1X", cw[i]);
}
printf("\n");
// check
errs = rs_decode(cw, err_pos, err_val);
if (errs) {
printf("errs: %d\n", errs);
printf("cw-dec:\n");
for (i = 0; i < rs_N; i++) {
//if (i == rs_R) printf(" ");
printf("%1X", cw[i]);
}
printf("\n");
}
#ifdef KA9Q
printf("\n");
printf("codeword\n");
printf("message: ");
for (i = 0; i < rs_K; i++) printf("%1x", msg[i]); printf("\n");
encode_rs_char(rs, msg, par);
printf("parity : ");
for (i = 0; i < rs_R; i++) printf("%1x", par[i]); printf("\n");
for (i = 0; i < rs_K; i++) codeword[i] = msg[i];
for (i = 0; i < rs_R; i++) codeword[rs_K+i] = par[i];
printf("codeword:\n");
for (i = 0; i < rs_N; i++) printf("%1x", codeword[i]); printf("\n");
#endif
}
printf("\n");
return 0;
}
/*
RS(15,9):
codeword length 15
message length 9
parity length 6
./ecc-rs15 str1 [str2]
str1: 9 nibbles (msg)
str2: 6 nibbles (par)
ecc-rs15 input/output: nibbles
cw[]: 1 byte / 1 nibble
examples:
$./ecc-rs15 000000001
msg: 000000001
cw
par: 342FA1
cw-enc:
342FA1000000001
codeword
message: 100000000
parity : 1af243
codeword:
1000000001af243
$./ecc-rs15 000000001 342FA1
msg: 000000001
par: 342FA1
cw
errs: 0
342FA1000000001
codeword
errors: 0
1000000001AF243
*/