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