diff options
Diffstat (limited to 'rstest.c')
-rw-r--r-- | rstest.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/rstest.c b/rstest.c new file mode 100644 index 0000000..539b40a --- /dev/null +++ b/rstest.c @@ -0,0 +1,296 @@ +/* Test the Reed-Solomon codecs + * for various block sizes and with random data and random error patterns + * + * Copyright 2002 Phil Karn, KA9Q + * May be used under the terms of the GNU Lesser General Public License (LGPL) + */ + +#include <stdio.h> +#include <stdlib.h> +#include <memory.h> +#include <time.h> +#include "fec.h" + + +struct etab { + int symsize; + int genpoly; + int fcs; + int prim; + int nroots; + int ntrials; +} Tab[] = { + {2, 0x7, 1, 1, 1, 10 }, + {3, 0xb, 1, 1, 2, 10 }, + {4, 0x13, 1, 1, 4, 10 }, + {5, 0x25, 1, 1, 6, 10 }, + {6, 0x43, 1, 1, 8, 10 }, + {7, 0x89, 1, 1, 10, 10 }, + {8, 0x11d, 1, 1, 32, 10 }, + {8, 0x187, 112,11, 32, 10 }, /* Duplicates CCSDS codec */ + {9, 0x211, 1, 1, 32, 10 }, + {10,0x409, 1, 1, 32, 10 }, + {11,0x805, 1, 1, 32, 10 }, + {12,0x1053, 1, 1, 32, 5 }, + {13,0x201b, 1, 1, 32, 2 }, + {14,0x4443, 1, 1, 32, 1 }, + {15,0x8003, 1, 1, 32, 1 }, + {16,0x1100b, 1, 1, 32, 1 }, + {0, 0, 0, 0, 0}, +}; + +int exercise_char(struct etab *e); +int exercise_int(struct etab *e); +int exercise_8(void); + +int main(){ + int i; + + srandom(time(NULL)); + + printf("Testing fixed CCSDS encoder...\n"); + exercise_8(); + for(i=0;Tab[i].symsize != 0;i++){ + int nn,kk; + + nn = (1<<Tab[i].symsize) - 1; + kk = nn - Tab[i].nroots; + printf("Testing (%d,%d) code...\n",nn,kk); + if(Tab[i].symsize <= 8) + exercise_char(&Tab[i]); + else + exercise_int(&Tab[i]); + } + exit(0); +} + +int exercise_8(void){ + int nn = 255; + unsigned char block[nn],tblock[nn]; + int errlocs[nn],derrlocs[nn]; + int i; + int errors; + int derrors,kk; + int errval,errloc; + int erasures; + int decoder_errors = 0; + + /* Compute code parameters */ + kk = 223; + + + /* Test up to the error correction capacity of the code */ + for(errors=0;errors<=(nn-kk)/2;errors++){ + + /* Load block with random data and encode */ + for(i=0;i<kk;i++) + block[i] = random() & nn; + memcpy(tblock,block,sizeof(block)); + encode_rs_8(block,&block[kk],0); + + /* Make temp copy, seed with errors */ + memcpy(tblock,block,sizeof(block)); + memset(errlocs,0,sizeof(errlocs)); + memset(derrlocs,0,sizeof(derrlocs)); + erasures=0; + for(i=0;i<errors;i++){ + do { + errval = random() & nn; + } while(errval == 0); /* Error value must be nonzero */ + + do { + errloc = random() % nn; + } while(errlocs[errloc] != 0); /* Must not choose the same location twice */ + + errlocs[errloc] = 1; + +#if FLAG_ERASURE + if(random() & 1) /* 50-50 chance */ + derrlocs[erasures++] = errloc; +#endif + tblock[errloc] ^= errval; + } + + /* Decode the errored block */ + derrors = decode_rs_8(tblock,derrlocs,erasures,0); + + if(derrors != errors){ + printf("(%d,%d) decoder says %d errors, true number is %d\n",nn,kk,derrors,errors); + decoder_errors++; + } + for(i=0;i<derrors;i++){ + if(errlocs[derrlocs[i]] == 0){ + printf("(%d,%d) decoder indicates error in location %d without error\n",nn,kk,derrlocs[i]); + decoder_errors++; + } + } + if(memcmp(tblock,block,sizeof(tblock)) != 0){ + printf("(%d,%d) decoder uncorrected errors! output ^ input:",nn,kk); + decoder_errors++; + for(i=0;i<nn;i++) + printf(" %02x",tblock[i] ^ block[i]); + printf("\n"); + } + } + return decoder_errors; +} + + +int exercise_char(struct etab *e){ + int nn = (1<<e->symsize) - 1; + unsigned char block[nn],tblock[nn]; + int errlocs[nn],derrlocs[nn]; + int i; + int errors; + int derrors,kk; + int errval,errloc; + int erasures; + int decoder_errors = 0; + void *rs; + + if(e->symsize > 8) + return -1; + + /* Compute code parameters */ + kk = nn - e->nroots; + + rs = init_rs_char(e->symsize,e->genpoly,e->fcs,e->prim,e->nroots,0); + if(rs == NULL){ + printf("init_rs_char failed!\n"); + return -1; + } + /* Test up to the error correction capacity of the code */ + for(errors=0;errors <= e->nroots/2;errors++){ + + /* Load block with random data and encode */ + for(i=0;i<kk;i++) + block[i] = random() & nn; + memcpy(tblock,block,sizeof(block)); + encode_rs_char(rs,block,&block[kk]); + + /* Make temp copy, seed with errors */ + memcpy(tblock,block,sizeof(block)); + memset(errlocs,0,sizeof(errlocs)); + memset(derrlocs,0,sizeof(derrlocs)); + erasures=0; + for(i=0;i<errors;i++){ + do { + errval = random() & nn; + } while(errval == 0); /* Error value must be nonzero */ + + do { + errloc = random() % nn; + } while(errlocs[errloc] != 0); /* Must not choose the same location twice */ + + errlocs[errloc] = 1; + +#if FLAG_ERASURE + if(random() & 1) /* 50-50 chance */ + derrlocs[erasures++] = errloc; +#endif + tblock[errloc] ^= errval; + } + + /* Decode the errored block */ + derrors = decode_rs_char(rs,tblock,derrlocs,erasures); + + if(derrors != errors){ + printf("(%d,%d) decoder says %d errors, true number is %d\n",nn,kk,derrors,errors); + decoder_errors++; + } + for(i=0;i<derrors;i++){ + if(errlocs[derrlocs[i]] == 0){ + printf("(%d,%d) decoder indicates error in location %d without error\n",nn,kk,derrlocs[i]); + decoder_errors++; + } + } + if(memcmp(tblock,block,sizeof(tblock)) != 0){ + printf("(%d,%d) decoder uncorrected errors! output ^ input:",nn,kk); + decoder_errors++; + for(i=0;i<nn;i++) + printf(" %02x",tblock[i] ^ block[i]); + printf("\n"); + } + } + + free_rs_char(rs); + return 0; +} + +int exercise_int(struct etab *e){ + int nn = (1<<e->symsize) - 1; + int block[nn],tblock[nn]; + int errlocs[nn],derrlocs[nn]; + int i; + int errors; + int derrors,kk; + int errval,errloc; + int erasures; + int decoder_errors = 0; + void *rs; + + /* Compute code parameters */ + kk = nn - e->nroots; + + rs = init_rs_int(e->symsize,e->genpoly,e->fcs,e->prim,e->nroots,0); + if(rs == NULL){ + printf("init_rs_int failed!\n"); + return -1; + } + /* Test up to the error correction capacity of the code */ + for(errors=0;errors <= e->nroots/2;errors++){ + + /* Load block with random data and encode */ + for(i=0;i<kk;i++) + block[i] = random() & nn; + memcpy(tblock,block,sizeof(block)); + encode_rs_int(rs,block,&block[kk]); + + /* Make temp copy, seed with errors */ + memcpy(tblock,block,sizeof(block)); + memset(errlocs,0,sizeof(errlocs)); + memset(derrlocs,0,sizeof(derrlocs)); + erasures=0; + for(i=0;i<errors;i++){ + do { + errval = random() & nn; + } while(errval == 0); /* Error value must be nonzero */ + + do { + errloc = random() % nn; + } while(errlocs[errloc] != 0); /* Must not choose the same location twice */ + + errlocs[errloc] = 1; + +#if FLAG_ERASURE + if(random() & 1) /* 50-50 chance */ + derrlocs[erasures++] = errloc; +#endif + tblock[errloc] ^= errval; + } + + /* Decode the errored block */ + derrors = decode_rs_int(rs,tblock,derrlocs,erasures); + + if(derrors != errors){ + printf("(%d,%d) decoder says %d errors, true number is %d\n",nn,kk,derrors,errors); + decoder_errors++; + } + for(i=0;i<derrors;i++){ + if(errlocs[derrlocs[i]] == 0){ + printf("(%d,%d) decoder indicates error in location %d without error\n",nn,kk,derrlocs[i]); + decoder_errors++; + } + } + if(memcmp(tblock,block,sizeof(tblock)) != 0){ + printf("(%d,%d) decoder uncorrected errors! output ^ input:",nn,kk); + decoder_errors++; + for(i=0;i<nn;i++) + printf(" %02x",tblock[i] ^ block[i]); + printf("\n"); + } + } + + free_rs_int(rs); + return 0; +} |