diff options
Diffstat (limited to 'src/golay23.c')
| -rw-r--r-- | src/golay23.c | 332 |
1 files changed, 168 insertions, 164 deletions
diff --git a/src/golay23.c b/src/golay23.c index 158a099..3b9790d 100644 --- a/src/golay23.c +++ b/src/golay23.c @@ -6,12 +6,13 @@ To test: - src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST && ./golay23 - src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST -DRUN_TIME_TABLES && ./golay23 - src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST -DNO_TABLES && ./golay23 + src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST && ./golay23 + src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST +-DRUN_TIME_TABLES && ./golay23 src$ gcc golay23.c -o golay23 -Wall -O3 +-DGOLAY23_UNITTEST -DNO_TABLES && ./golay23 To generate tables: - src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_MAKETABLES && ./golay23 + src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_MAKETABLES && ./golay23 \*---------------------------------------------------------------------------*/ @@ -44,24 +45,25 @@ int static encoding_table[4096]; int static decoding_table[2048]; static int inited = 0; #else -//default is to use precomputed tables -#include "golayenctable.h" +// default is to use precomputed tables #include "golaydectable.h" +#include "golayenctable.h" #endif #endif -//since we want to avoid bit-reversing inside syndrome() we bit-reverse the polynomial instead -#define GOLAY_POLYNOMIAL 0xC75 //AE3 reversed +// since we want to avoid bit-reversing inside syndrome() we bit-reverse the +// polynomial instead +#define GOLAY_POLYNOMIAL 0xC75 // AE3 reversed int golay23_syndrome(int c) { - //could probably be done slightly smarter, but works - int x; - for (x = 11; x >= 0; x--) { - if (c & ((1<<11) << x)) { - c ^= GOLAY_POLYNOMIAL << x; - } + // could probably be done slightly smarter, but works + int x; + for (x = 11; x >= 0; x--) { + if (c & ((1 << 11) << x)) { + c ^= GOLAY_POLYNOMIAL << x; } - return c; + } + return c; } #ifdef __GNUC__ @@ -71,124 +73,124 @@ int golay23_syndrome(int c) { #define popcount __popcnt #else static int popcount(unsigned int c) { - int ret = 0; - while (c) { - if (c & 1) { - ret++; - } - c >>= 1; + int ret = 0; + while (c) { + if (c & 1) { + ret++; } - return ret; + c >>= 1; + } + return ret; } #endif #if defined(NO_TABLES) || defined(RUN_TIME_TABLES) static int golay23_encode_no_tables(int c) { - c <<= 11; - return golay23_syndrome(c) | c; + c <<= 11; + return golay23_syndrome(c) | c; } #endif #ifdef NO_TABLES static int unrotate(unsigned int c, int x) { - return ((c << x) & 0x7FFFFF) | (c >> (23 - x)); + return ((c << x) & 0x7FFFFF) | (c >> (23 - x)); } static int golay23_decode_no_tables(int c) { - //TODO: optimize? - int x; - c = unrotate(c, 12); - - for (x = 0; x < 23; x++) { - int t; - int s = golay23_syndrome(c); + // TODO: optimize? + int x; + c = unrotate(c, 12); - if (popcount(s) <= 3) { - return unrotate(c ^ s, x) & 0xFFF; - } + for (x = 0; x < 23; x++) { + int t; + int s = golay23_syndrome(c); - for (t = 0; t < 23; t++) { - int c2 = c ^ (1 << t); - int s = golay23_syndrome(c2); + if (popcount(s) <= 3) { + return unrotate(c ^ s, x) & 0xFFF; + } - if (popcount(s) <= 2) { - return unrotate(c2 ^ s, x) & 0xFFF; - } - } + for (t = 0; t < 23; t++) { + int c2 = c ^ (1 << t); + int s = golay23_syndrome(c2); - //rotate - c = (c >> 1) | ((c & 1) << 22); + if (popcount(s) <= 2) { + return unrotate(c2 ^ s, x) & 0xFFF; + } } - //shouldn't reach here.. - assert("Something is wrong with golay23_decode_no_tables().."); - return c & 0xFFF; + // rotate + c = (c >> 1) | ((c & 1) << 22); + } + + // shouldn't reach here.. + assert("Something is wrong with golay23_decode_no_tables().."); + return c & 0xFFF; } #endif void golay23_init(void) { #ifdef RUN_TIME_TABLES - int x, y, z; - inited = 1; - for (x = 0; x < 4096; x++) { - encoding_table[x] = golay23_encode_no_tables(x); + int x, y, z; + inited = 1; + for (x = 0; x < 4096; x++) { + encoding_table[x] = golay23_encode_no_tables(x); + } + + decoding_table[0] = 0; + // 1-bit errors + for (x = 0; x < 23; x++) { + int d = 1 << x; + decoding_table[golay23_syndrome(d)] = d; + } + // 2-bit errors + for (x = 0; x < 22; x++) { + for (y = x + 1; y < 23; y++) { + int d = (1 << x) | (1 << y); + decoding_table[golay23_syndrome(d)] = d; } - - decoding_table[0] = 0; - //1-bit errors - for (x = 0; x < 23; x++) { - int d = 1<<x; + } + // 3-bit errors + for (x = 0; x < 21; x++) { + for (y = x + 1; y < 22; y++) { + for (z = y + 1; z < 23; z++) { + int d = (1 << x) | (1 << y) | (1 << z); decoding_table[golay23_syndrome(d)] = d; + } } - //2-bit errors - for (x = 0; x < 22; x++) { - for (y = x+1; y < 23; y++) { - int d = (1<<x) | (1<<y); - decoding_table[golay23_syndrome(d)] = d; - } - } - //3-bit errors - for (x = 0; x < 21; x++) { - for (y = x+1; y < 22; y++) { - for (z = y+1; z < 23; z++) { - int d = (1<<x) | (1<<y) | (1<<z); - decoding_table[golay23_syndrome(d)] = d; - } - } - } + } #endif } -int golay23_encode(int c) { - assert(c >= 0 && c <= 0xFFF); +int golay23_encode(int c) { + assert(c >= 0 && c <= 0xFFF); #ifdef RUN_TIME_TABLES - assert(inited); + assert(inited); #endif #ifdef NO_TABLES - return golay23_encode_no_tables(c); + return golay23_encode_no_tables(c); #else - return encoding_table[c]; + return encoding_table[c]; #endif } -int golay23_decode(int c) { - assert(c >= 0 && c <= 0x7FFFFF); +int golay23_decode(int c) { + assert(c >= 0 && c <= 0x7FFFFF); #ifdef RUN_TIME_TABLES - assert(inited); + assert(inited); #endif #ifdef NO_TABLES - //duplicate old golay23_decode()'s shift - return unrotate(golay23_decode_no_tables(c), 11); + // duplicate old golay23_decode()'s shift + return unrotate(golay23_decode_no_tables(c), 11); #else - //message is shifted 11 places left in the return value - return c ^ decoding_table[golay23_syndrome(c)]; + // message is shifted 11 places left in the return value + return c ^ decoding_table[golay23_syndrome(c)]; #endif } -int golay23_count_errors(int recd_codeword, int corrected_codeword) { - return popcount(recd_codeword ^ corrected_codeword); +int golay23_count_errors(int recd_codeword, int corrected_codeword) { + return popcount(recd_codeword ^ corrected_codeword); } /** @@ -199,113 +201,115 @@ int golay23_count_errors(int recd_codeword, int corrected_codeword) { #include <stdio.h> int main() { - int x; - //generate and dump - golay23_init(); + int x; + // generate and dump + golay23_init(); - FILE *enc = fopen("golayenctable.h", "w"); - FILE *dec = fopen("golaydectable.h", "w"); + FILE *enc = fopen("golayenctable.h", "w"); + FILE *dec = fopen("golaydectable.h", "w"); - fprintf(enc, "/* Generated by golay23.c -DGOLAY23_MAKETABLE */\n\ + fprintf(enc, + "/* Generated by golay23.c -DGOLAY23_MAKETABLE */\n\ \n\ const int static encoding_table[]={\n"); - for (x = 0; x < 4096; x++) { - fprintf(enc, x < 4095 ? " 0x%x,\n" : " 0x%x\n", encoding_table[x]); - } - fprintf(enc, "};\n"); + for (x = 0; x < 4096; x++) { + fprintf(enc, x < 4095 ? " 0x%x,\n" : " 0x%x\n", encoding_table[x]); + } + fprintf(enc, "};\n"); - fprintf(dec, "/* Generated by golay23.c -DGOLAY23_MAKETABLE */\n\ + fprintf(dec, + "/* Generated by golay23.c -DGOLAY23_MAKETABLE */\n\ \n\ const int static decoding_table[]={\n"); - for (x = 0; x < 2048; x++) { - fprintf(dec, x < 2047 ? " 0x%x,\n" : " 0x%x\n", decoding_table[x]); - } - fprintf(dec, "};\n"); + for (x = 0; x < 2048; x++) { + fprintf(dec, x < 2047 ? " 0x%x,\n" : " 0x%x\n", decoding_table[x]); + } + fprintf(dec, "};\n"); - fclose(enc); - fclose(dec); + fclose(enc); + fclose(dec); - return 0; + return 0; } #elif defined(GOLAY23_UNITTEST) +#include <memory.h> #include <stdio.h> #include <stdlib.h> -#include <memory.h> int main() { - int c; + int c; + + golay23_init(); + + // keep track of whether every single codeword has been checked + char *checkmask = malloc(1 << 23); + memset(checkmask, 0, 1 << 23); - golay23_init(); + // step through all possible messages + for (c = 0; c < (1 << 12); c++) { + int g23 = golay23_encode(c); + int x, y, z; + checkmask[g23] = 1; + int c2 = golay23_decode(g23) >> 11; - //keep track of whether every single codeword has been checked - char *checkmask = malloc(1<<23); - memset(checkmask, 0, 1<<23); + printf("%03x -> %06x %03x\n", c, g23, c2); - //step through all possible messages - for (c = 0; c < (1<<12); c++) { - int g23 = golay23_encode(c); - int x,y,z; - checkmask[g23] = 1; - int c2 = golay23_decode(g23) >> 11; + if (c != c2) { + printf("Bad!\n"); + exit(1); + } - printf("%03x -> %06x %03x\n", c, g23, c2); + // test the code by flipping every combination of one, two and three bits + for (x = 0; x < 23; x++) { + int flipped = g23 ^ (1 << x); + checkmask[flipped] = 1; + int c2 = golay23_decode(flipped) >> 11; + if (c != c2) { + printf("Bad!\n"); + + exit(1); + } + } + for (x = 0; x < 22; x++) { + for (y = x + 1; y < 23; y++) { + int flipped = g23 ^ (1 << x) ^ (1 << y); + checkmask[flipped] = 1; + int c2 = golay23_decode(flipped) >> 11; if (c != c2) { - printf("Bad!\n"); - exit(1); - } + printf("Bad!\n"); - //test the code by flipping every combination of one, two and three bits - for (x = 0; x < 23; x++) { - int flipped = g23 ^ (1<<x); - checkmask[flipped] = 1; - int c2 = golay23_decode(flipped) >> 11; - if (c != c2) { - printf("Bad!\n"); - - exit(1); - } - } - - for (x = 0; x < 22; x++) { - for (y = x+1; y < 23; y++) { - int flipped = g23 ^ (1<<x) ^ (1<<y); - checkmask[flipped] = 1; - int c2 = golay23_decode(flipped) >> 11; - if (c != c2) { - printf("Bad!\n"); - - exit(1); - } - } - } - - for (x = 0; x < 21; x++) { - for (y = x+1; y < 22; y++) { - for (z = y+1; z < 23; z++) { - int flipped = g23 ^ (1<<x) ^ (1<<y) ^ (1<<z); - checkmask[flipped] = 1; - int c2 = golay23_decode(flipped) >> 11; - if (c != c2) { - printf("Bad!\n"); - exit(1); - } - } - } + exit(1); } + } } - //did we check every codeword? - for (c = 0; c < (1<<23); c++) { - if (checkmask[c] != 1) { - printf("%06x unchecked!\n", c); + for (x = 0; x < 21; x++) { + for (y = x + 1; y < 22; y++) { + for (z = y + 1; z < 23; z++) { + int flipped = g23 ^ (1 << x) ^ (1 << y) ^ (1 << z); + checkmask[flipped] = 1; + int c2 = golay23_decode(flipped) >> 11; + if (c != c2) { + printf("Bad!\n"); exit(1); + } } + } + } + } + + // did we check every codeword? + for (c = 0; c < (1 << 23); c++) { + if (checkmask[c] != 1) { + printf("%06x unchecked!\n", c); + exit(1); } + } - printf("Everything checks out\n"); - free(checkmask); - return 0; + printf("Everything checks out\n"); + free(checkmask); + return 0; } #endif |
