kopia lustrzana https://github.com/rs1729/RS
reed-solomon ecc: GF(16) - RS(15,9) (example)
rodzic
923e6b17fd
commit
7d8383221e
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
*/
|
||||
|
||||
|
Ładowanie…
Reference in New Issue