lin
2025-08-01 633231e833e21d5b8b1c00cb15aedb62b3b78e8f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* Exercise an RS codec a specified number of times using random
 * data and error patterns
 *
 * Copyright 2002 Phil Karn, KA9Q
 * May be used under the terms of the GNU Lesser General Public License (LGPL)
 */
#define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#ifdef FIXED
#include "fixed.h"
#define EXERCISE exercise_8
#elif defined(CCSDS)
#include "fixed.h"
#include "ccsds.h"
#define EXERCISE exercise_ccsds
#elif defined(BIGSYM)
#include "int.h"
#define EXERCISE exercise_int
#else
#include "char.h"
#define EXERCISE exercise_char
#endif
 
#ifdef FIXED
#define PRINTPARM printf("(255,223):");
#elif defined(CCSDS)
#define PRINTPARM printf("CCSDS (255,223):");
#else
#define PRINTPARM printf("(%d,%d):",rs->nn,rs->nn-rs->nroots);
#endif
 
/* Exercise the RS codec passed as an argument */
int EXERCISE(
#if !defined(CCSDS) && !defined(FIXED)
void *p,
#endif
int trials){
#if !defined(CCSDS) && !defined(FIXED)
  struct rs *rs = (struct rs *)p;
#endif
  data_t block[NN],tblock[NN];
  int i;
  int errors;
  int errlocs[NN];
  int derrlocs[NROOTS];
  int derrors;
  int errval,errloc;
  int erasures;
  int decoder_errors = 0;
 
  while(trials-- != 0){
    /* Test up to the error correction capacity of the code */
    for(errors=0;errors <= NROOTS/2;errors++){
 
      /* Load block with random data and encode */
      for(i=0;i<NN-NROOTS;i++)
   block[i] = random() & NN;
      
#if defined(CCSDS) || defined(FIXED)
      ENCODE_RS(&block[0],&block[NN-NROOTS],0);
#else
      ENCODE_RS(rs,&block[0],&block[NN-NROOTS]);
#endif
 
      /* Make temp copy, seed with errors */
      memcpy(tblock,block,sizeof(tblock));
      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 */
#if defined(CCSDS) || defined(FIXED)
      derrors = DECODE_RS(tblock,derrlocs,erasures,0);
#else
      derrors = DECODE_RS(rs,tblock,derrlocs,erasures);
#endif
 
      if(derrors != errors){
   PRINTPARM
   printf(" decoder says %d errors, true number is %d\n",derrors,errors);
   decoder_errors++;
      }
      for(i=0;i<derrors;i++){
   if(errlocs[derrlocs[i]] == 0){
     PRINTPARM
     printf(" decoder indicates error in location %d without error\n",derrlocs[i]);
     decoder_errors++;
   }
      }
      if(memcmp(tblock,block,sizeof(tblock)) != 0){
   PRINTPARM
   printf(" uncorrected errors! output ^ input:");
   decoder_errors++;
   for(i=0;i<NN;i++)
     printf(" %02x",tblock[i] ^ block[i]);
   printf("\n");
      }
    }
  }
  return decoder_errors;
}