TECHNICAL DESCRIPTION OF THE GOLAY CODE:

GOLAY CODE: This code is used in several military digital data communication equipment.

REFERENCE: WEB SITE:http://is1.websearch.com/websrch.bar.inkto/search/inc/results/web/framed.htm?display-url=http%3A%2F%2Fwww.the-art-of-ecc.com%2F2_Short&qkw=Hamming+Algorithm&nextid=di3:1098595064118&frame=http%3A%2F%2Fclickit.go2net.com%2Fsearch%3Fpos%3D12%26ppos%3D4%26plnks%3D4%26uplnks%3D9%26cat%3Dweb%26cid%3D239170%26site%3Dsrch%26area%3Dsrch.noncomm.inktomi%26shape%3Dtextlink%26cp%3Dwebsrch.bar.inkto%26cluster-click%3D0%26pd%3D0%26coll%3D0%26query%3Dhamming%2Balgorithm%26rawto%3Dhttp%3A%2F%2Fwww.the-art-of-ecc.com%2F2_Short

Golay code: The following is a description of the Golay code that can correct up to three errors with a minimum distance of seven:

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);

GOLAY CODE 24.C

Reference:  R.H. Morelos-Zaragoza, The Art of Error Correcting Coding, Wiley, 2002.

//

// ISBN 0471 49581 6

Web site: http://is1.websearch.com/websrch.bar.inkto/search/inc/results/web/framed.htm?display-url=http%3A%2F%2Fwww.the-art-of-ecc.com%2F2_Short&qkw=Hamming+Algorithm&nextid=di3:1098595064118&frame=http%3A%2F%2Fclickit.go2net.com%2Fsearch%3Fpos%3D12%26ppos%3D4%26plnks%3D4%26uplnks%3D9%26cat%3Dweb%26cid%3D239170%26site%3Dsrch%26area%3Dsrch.noncomm.inktomi%26shape%3Dtextlink%26cp%3Dwebsrch.bar.inkto%26cluster-click%3D0%26pd%3D0%26coll%3D0%26query%3Dhamming%2Balgorithm%26rawto%3Dhttp%3A%2F%2Fwww.the-art-of-ecc.com%2F2_Short

File: golay24.c

//

//  An arithmetic decoder for the (24,12,8) Golay code.

//  Note: The C code below assumes execution in a 16-bit computer.

//  Inspired by Stephen Wicker's book, pp. 143-144.

// ------------------------------------------------------------------------

// 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>

#include <math.h>

main()

 {

   /* Array x contains the twelve rows (columns) of the identity matrix */

   int x[12] = { 0x800, 0x400, 0x200, 0x100, 0x080, 0x040,

                                 0x020, 0x010, 0x008, 0x004, 0x002, 0x001 };

   /* Array y contains the twelve rows (columns) of the parity-check matrix */

   int y[12] = { 0x7ff, 0xee2, 0xdc5, 0xb8b, 0xf16, 0xe2d,

                                 0xc5b, 0x8b7, 0x96e, 0xadc, 0xdb8, 0xb71 };

   int c[2];          /* Codeword composed of 12-bit info and 12-bit parity */

   int r[2];          /* Received vector in two halfs of 12 bits each */

   int e[2];          /* Estimated error vector */

   int s;             /* syndrome */

   int q;             /* modified syndrome */

   int c_hat[2];      /* Estimated codeword */

   int i,j;

   int aux, found;

   int weight(int vector);

   long seed;

   /* -------------- Random generation of a codeword ----------------- */

   time(&seed);

   srandom(seed);

   c[0] = random()&0xfff;

   c[1] = 0;

   for (i=0; i<12; i++)

     {

       aux = 0;

       for (j=0; j<12; j++)

                 aux = aux ^ ( (c[0]&y[i])>>j & 0x01);

       c[1] = (c[1] << 1) ^ aux;

     }

   printf("c =%3x%3x\n", c[0], c[1]);

   /* --------------------- Introduce errors ------------------------- */

   e[0] = random()&0x030;

   e[1] = random()&0x101;

   printf("e =%3x%3x, w(e) = %d\n", e[0], e[1], weight(e[0])+weight(e[1]));

   /* ---------------------- Received word --------------------------- */

   r[0] = c[0]^e[0];

   r[1] = c[1]^e[1];

   /******* STEP 1: Compute the syndrome of the received vector ********/

   s = 0;

   for (j=0; j<12; j++)

     {

       aux = 0;

       for (i=0; i<12; i++)

                 aux = aux ^ ( (x[j]&r[0])>>i& 0x01 ); /* identity part */

       for (i=0; i<12; i++)

                 aux = aux ^ ( (y[j]&r[1])>>i& 0x01 ); /* parity part */

       s = (s<<1)^aux;

     }

   printf("r =%3x%3x, s = %x, w(s) = %d\n", r[0], r[1], s, weight(s));

   /******* STEP 2 */

   printf("Step 2\n");

   if (weight(s)<=3)

     {

       e[0] = s;

       e[1] = 0;

     }

   else

     {

       /******* STEP 3 */

       printf("Step 3\n");

       i = 0;

       found = 0;

       do {

                 if (weight(s^y[i]) <=2)

                   {

                     e[0] = s^y[i];

                     e[1] = x[i];

                     found = 1;

                   }

                 i++;

       } while ( (i<12) && (!found) );

       if (( i==12 ) && (!found))

                 {

                   /******* STEP 4 */

                   printf("Step 4\n");

                   q = 0;

                   for (j=0; j<12; j++)

                     {

                       aux = 0;

                       for (i=0; i<12; i++)

                                 aux = aux ^ ( (y[j]&s)>>i & 0x01 );

                       q = (q<<1) ^ aux;

                     }

                   /******* STEP 5 */

                   printf("Step 5\n");

                   if (weight(q) <=3)

                     {

                       e[0] = 0;

                       e[1] = q;

                     }

                   else

                     {

                       /******* STEP 6 */

                       printf("Step 6\n");

                       i = 0;

                       found = 0;

                       do {

                                 if (weight(q^y[i]) <=2)

                                   {

                                     e[0] = x[i];

                                     e[1] = q^y[i];

                                     found = 1;

                                   }

                                 i++;

                       } while ( (i<12) && (!found) );

                      

                       if ((i==12) && (!found))

                                 {

                                   /******* STEP 7 */

                                   printf("uncorrectable error pattern\n");

                                   /* You can raise a flag here, or output the vector as is */

                                   exit(1);

                                 }

                     }

                 }

     }

   /* ------------------- Correct received word --------------------- */

   c_hat[0] = r[0]^e[0];

   c_hat[1] = r[1]^e[1];

   printf("Estimated codeword =%x%x\n", c_hat[0], c_hat[1]);

 }

/* Function to compute the Hamming weight of a 12-bit integer */

int weight(int vector)

 {

   int i, aux;

   aux = 0;

   for (i=0; i<12; i++)

     if ( (vector>>i)&1 )

       aux++;

   return(aux);