⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 golay23.c

📁 详细讲述纠错码的书籍
💻 C
字号:
// ------------------------------------------------------------------------
// File:    golay23.c
// Title:   Encoder/decoder for the binary (23,12,7) Golay code
// Date:    August 1994
//
// The binary (23,12,7) Golay code is an example of a perfect code, that is,
// the number of syndromes equals the number of correctable error patterns.
// The minimum distance is 7, so all error patterns of Hamming weight up to
// 3 can be corrected. The total number of these error patterns is:
//
//       Number of errors         Number of patterns
//       ----------------         ------------------
//              0                         1
//              1                        23
//              2                       253
//              3                      1771
//                                     ----
//    Total number of error patterns = 2048 = 2^{11} = number of syndromes
//                                               --
//               number of redundant bits -------^
//
// Because of its relatively low length (23), dimension (12) and number of
// redundant bits (11), the binary (23,12,7) Golay code can be encoded and
// decoded simply by using look-up tables. The program below uses a 16K 
// encoding table and an 8K decoding table.
// ------------------------------------------------------------------------
// This program is complementary material for the book:
//
// R.H. Morelos-Zaragoza, The Art of Error Correcting Coding, Wiley, 2002.
//
// ISBN 0471 49581 6
//
// This and other programs are available at http://the-art-of-ecc.com
//
// You may use this program for academic and personal purposes only. 
// If this program is used to perform simulations whose results are 
// published in a journal or book, please refer to the book above.
//
// The use of this program in a commercial product requires explicit
// written permission from the author. The author is not responsible or 
// liable for damage or loss that may be caused by the use of this program. 
//
// Copyright (c) 2002. Robert H. Morelos-Zaragoza. All rights reserved.
// ------------------------------------------------------------------------
 

#include <stdio.h>
#define X22             0x00400000   /* vector representation of X^{22} */
#define X11             0x00000800   /* vector representation of X^{11} */
#define MASK12          0xfffff800   /* auxiliary vector for testing */
#define GENPOL          0x00000c75   /* generator polinomial, g(x) */

/* Global variables:
 *
 * pattern = error pattern, or information, or received vector
 * encoding_table[] = encoding table
 * decoding_table[] = decoding table
 * data = information bits, i(x)
 * codeword = code bits = x^{11}i(x) + (x^{11}i(x) mod g(x))
 * numerr = number of errors = Hamming weight of error polynomial e(x)
 * position[] = error positions in the vector representation of e(x)
 * recd = representation of corrupted received polynomial r(x) = c(x) + e(x)
 * decerror = number of decoding errors
 * a[] = auxiliary array to generate correctable error patterns
 */

long pattern;
long encoding_table[4096], decoding_table[2048];
long data, codeword, recd;
long position[23] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008,
                      0x00000010, 0x00000020, 0x00000040, 0x00000080,
                      0x00000100, 0x00000200, 0x00000400, 0x00000800,
                      0x00001000, 0x00002000, 0x00004000, 0x00008000,
                      0x00010000, 0x00020000, 0x00040000, 0x00080000,
                      0x00100000, 0x00200000, 0x00400000 };
long numerr, errpos[23], decerror = 0;
int a[4];

long arr2int(a,r)
/*
 * Convert a binary vector of Hamming weight r, and nonzero positions in
 * array a[1]...a[r], to a long integer \sum_{i=1}^r 2^{a[i]-1}.
 */
int r;
int *a;
{
   int i;
   long mul, result = 0, temp;
 
   for (i=1; i<=r; i++) {
      mul = 1;
      temp = a[i]-1;
      while (temp--)
         mul = mul << 1;
      result += mul;
      }
   return(result);
}

void nextcomb(n, r, a)
/*
 * Calculate next r-combination of an n-set.
 */
int  n, r;
int  *a;
{
  int  i, j;
 
  a[r]++;
  if (a[r] <= n)
      return;
  j = r - 1;
  while (a[j] == n - r + j)
     j--;
  for (i = r; i >= j; i--)
      a[i] = a[j] + i - j + 1;
  return;
}

long get_syndrome(pattern)
/*
 * Compute the syndrome corresponding to the given pattern, i.e., the
 * remainder after dividing the pattern (when considering it as the vector
 * representation of a polynomial) by the generator polynomial, GENPOL.
 * In the program this pattern has several meanings: (1) pattern = infomation
 * bits, when constructing the encoding table; (2) pattern = error pattern,
 * when constructing the decoding table; and (3) pattern = received vector, to
 * obtain its syndrome in decoding.
 */
long pattern;
{
    long aux = X22, aux2;
 
    if (pattern >= X11)
       while (pattern & MASK12) {
           while (!(aux & pattern))
              aux = aux >> 1;
           pattern ^= (aux/X11) * GENPOL;
           }
    return(pattern);
}

main()
{
   register int i,j;
   long temp;
   int seed = 133757;

   /*
    * ---------------------------------------------------------------------
    *                  Generate ENCODING TABLE
    *
    * An entry to the table is an information vector, a 32-bit integer,
    * whose 12 least significant positions are the information bits. The
    * resulting value is a codeword in the (23,12,7) Golay code: A 32-bit
    * integer whose 23 least significant bits are coded bits: Of these, the
    * 12 most significant bits are information bits and the 11 least
    * significant bits are redundant bits (systematic encoding).
    * --------------------------------------------------------------------- 
    */
    for (pattern = 0; pattern < 4096; pattern++) {
        temp = pattern << 11;          /* multiply information by X^{11} */
        encoding_table[pattern] = temp + get_syndrome(temp);/* add redundancy */
        }

   /*
    * ---------------------------------------------------------------------
    *                  Generate DECODING TABLE
    *
    * An entry to the decoding table is a syndrome and the resulting value
    * is the most likely error pattern. First an error pattern is generated.
    * Then its syndrome is calculated and used as a pointer to the table
    * where the error pattern value is stored.
    * --------------------------------------------------------------------- 
    *            
    * (1) Error patterns of WEIGHT 1 (SINGLE ERRORS)
    */
    decoding_table[0] = 0;
    decoding_table[1] = 1;
    temp = 1; 
    for (i=2; i<= 23; i++) {
        temp *= 2;
        decoding_table[get_syndrome(temp)] = temp;
        }
   /*            
    * (2) Error patterns of WEIGHT 2 (DOUBLE ERRORS)
    */
    a[1] = 1; a[2] = 2;
    temp = arr2int(a,2);
    decoding_table[get_syndrome(temp)] = temp;
    for (i=1; i<253; i++) {
        nextcomb(23,2,a);
        temp = arr2int(a,2);
        decoding_table[get_syndrome(temp)] = temp;
        }
   /*            
    * (3) Error patterns of WEIGHT 3 (TRIPLE ERRORS)
    */
    a[1] = 1; a[2] = 2; a[3] = 3;
    temp = arr2int(a,3);
    decoding_table[get_syndrome(temp)] = temp;
    for (i=1; i<1771; i++) {
        nextcomb(23,3,a);
        temp = arr2int(a,3);
        decoding_table[get_syndrome(temp)] = temp;
        }

   /* ---------------------------------------------------------------------
    *                        Generate DATA
    * ---------------------------------------------------------------------
    */
    srandom(seed);
    /*
     * data = 12 information bits, an information polynomial i(x)
     */
    data = random() & 0x00000fff;
    printf("data =            %#012x\n", data);

   /*
    * ---------------------------------------------------------------------
    *                         ENCODING
    * ---------------------------------------------------------------------
    */
    codeword = encoding_table[data];
    printf("codeword =        %#012x\n", codeword);

   /*
    * ---------------------------------------------------------------------
    *                          ERRORS
    * ---------------------------------------------------------------------
    */
    printf("Enter the number of errors and their positions (0...22): ");
    scanf("%d", &numerr);
    for (i = 0; i < numerr; i++)
        scanf("%d", &errpos[i]);

   /*
    * ---------------------------------------------------------------------
    *                      RECEIVED VECTOR
    * ---------------------------------------------------------------------
    */
    recd = codeword;
    if (numerr)
        for (i = 0; i < numerr; i++)
            recd ^= position[errpos[i]];
    printf("received vector = %#012x\n", recd);

   /*
    * ---------------------------------------------------------------------
    *                         DECODING
    * ---------------------------------------------------------------------
    */
    printf("syndrome =        %#012x\n", get_syndrome(recd));
    printf("error pattern =   %#012x\n", decoding_table[get_syndrome(recd)]);
   /*
    * Calculate the syndrome, look up the corresponding error pattern and
    * add it to the received vector.
    */
    recd ^= decoding_table[get_syndrome(recd)];
    printf("decoded vector =  %#012x\n", recd);
    printf("recovered data =  %#012x\n", (recd>>11));
    printf("original data  =  %#012x\n", data);
   /*
    * DECODING ERRORS? Only the data portion is compared. Note that this
    * is only possible in a simulation!
    */
    pattern = (recd ^ codeword) >> 11;
    for (i=0; i<12; i++)
       if (pattern&position[i])
          decerror++;
    printf("there were %d decoding errors\n", decerror);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -