mirror of
https://github.com/aicodix/code.git
synced 2026-04-27 14:30:36 +00:00
added encoder and syndrome decoder for short BCH codes
This commit is contained in:
parent
1b4899c66d
commit
5d944ca7a9
6 changed files with 258 additions and 0 deletions
|
|
@ -52,6 +52,14 @@ Implemented are the following Encoders and Decoders:
|
|||
* [bose_chaudhuri_hocquenghem_encoder.hh](bose_chaudhuri_hocquenghem_encoder.hh)
|
||||
* [bose_chaudhuri_hocquenghem_decoder.hh](bose_chaudhuri_hocquenghem_decoder.hh)
|
||||
|
||||
### [short_bch_code_encoder.hh](short_bch_code_encoder.hh)
|
||||
|
||||
Encoder for short [BCH codes](https://en.wikipedia.org/wiki/BCH_code)
|
||||
|
||||
### [short_bch_code_decoder.hh](short_bch_code_decoder.hh)
|
||||
|
||||
[Syndrome decoder](https://en.wikipedia.org/wiki/Decoding_methods#Syndrome_decoding) for short [BCH codes](https://en.wikipedia.org/wiki/BCH_code)
|
||||
|
||||
### [simplex_encoder.hh](simplex_encoder.hh)
|
||||
|
||||
Encoder for [Simplex codes](https://en.wikipedia.org/wiki/Linear_code).
|
||||
|
|
|
|||
56
short_bch_code_decoder.hh
Normal file
56
short_bch_code_decoder.hh
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Decoder for short BCH codes
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace CODE {
|
||||
|
||||
template <int N, int K>
|
||||
class ShortBCHCodeDecoder
|
||||
{
|
||||
static const int P = N - K;
|
||||
static const int W = 1 << K;
|
||||
static const int R = 1 << P;
|
||||
int err[R];
|
||||
short par[W];
|
||||
static_assert(N < 8 * sizeof(err[0]), "codeword type not wide enough");
|
||||
static_assert(P < 8 * sizeof(par[0]), "parity type not wide enough");
|
||||
static int modgen(int inp, int gen)
|
||||
{
|
||||
for (int i = K-1; i >= 0; --i) {
|
||||
int tmp = inp >> (i+P);
|
||||
inp ^= (tmp & 1) * (gen << i);
|
||||
}
|
||||
return inp;
|
||||
}
|
||||
public:
|
||||
ShortBCHCodeDecoder(int generator, int T)
|
||||
{
|
||||
for (int i = 0; i < W; ++i)
|
||||
par[i] = modgen(i << P, generator);
|
||||
err[0] = 0;
|
||||
assert(T > 0 && T <= 4);
|
||||
for (int a = 1<<(N-1); T >= 1 && a; a >>= 1) {
|
||||
err[modgen(a, generator)] = a;
|
||||
for (int b = a >> 1; T >= 2 && b; b >>= 1) {
|
||||
err[modgen(a|b, generator)] = a|b;
|
||||
for (int c = b >> 1; T >= 3 && c; c >>= 1) {
|
||||
err[modgen(a|b|c, generator)] = a|b|c;
|
||||
for (int d = c >> 1; T >= 4 && d; d >>= 1) {
|
||||
err[modgen(a|b|c|d, generator)] = a|b|c|d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int operator()(int inp)
|
||||
{
|
||||
return inp ^ err[(par[inp>>P] ^ inp) & (R-1)];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
40
short_bch_code_encoder.hh
Normal file
40
short_bch_code_encoder.hh
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Encoder for short BCH codes
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace CODE {
|
||||
|
||||
template <int N, int K>
|
||||
class ShortBCHCodeEncoder
|
||||
{
|
||||
static const int P = N - K;
|
||||
static const int W = 1 << K;
|
||||
short par[W];
|
||||
static_assert(N < 8 * sizeof(int), "codeword type not wide enough");
|
||||
static_assert(P < 8 * sizeof(par[0]), "parity type not wide enough");
|
||||
static int modgen(int inp, int gen)
|
||||
{
|
||||
for (int i = K-1; i >= 0; --i) {
|
||||
int tmp = inp >> (i+P);
|
||||
inp ^= (tmp & 1) * (gen << i);
|
||||
}
|
||||
return inp;
|
||||
}
|
||||
public:
|
||||
ShortBCHCodeEncoder(int generator)
|
||||
{
|
||||
for (int i = 0; i < W; ++i)
|
||||
par[i] = modgen(i << P, generator);
|
||||
}
|
||||
int operator()(int msg)
|
||||
{
|
||||
return (msg << P) | par[msg];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
59
tests/short_bch_code_decoder_test.cc
Normal file
59
tests/short_bch_code_decoder_test.cc
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Test for the short BCH codes decoder
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "short_bch_code_decoder.hh"
|
||||
|
||||
int main()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::default_random_engine generator(rd());
|
||||
if (1) {
|
||||
// Perfect binary Golay code using x^11+x^9+x^7+x^6+x^5+x+1
|
||||
const int N = 23, K = 12, T = 3, POLY = 0b101011100011;
|
||||
CODE::ShortBCHCodeDecoder<N, K> decode(POLY, T);
|
||||
int target = 0b10101101101111011111001;
|
||||
int damaged = target;
|
||||
typedef std::uniform_int_distribution<int> distribution;
|
||||
auto epos = std::bind(distribution(0, N-1), generator);
|
||||
for (int i = 0; i < T; ++i)
|
||||
damaged ^= 1 << epos();
|
||||
int recovered = decode(damaged);
|
||||
assert(recovered == target);
|
||||
}
|
||||
if (1) {
|
||||
// Perfect binary Golay code using x^11+x^10+x^6+x^5+x^4+x^2+1
|
||||
const int N = 23, K = 12, T = 3, POLY = 0b110001110101;
|
||||
CODE::ShortBCHCodeDecoder<N, K> decode(POLY, T);
|
||||
int target = 0b10101101101100100010101;
|
||||
int damaged = target;
|
||||
typedef std::uniform_int_distribution<int> distribution;
|
||||
auto epos = std::bind(distribution(0, N-1), generator);
|
||||
for (int i = 0; i < T; ++i)
|
||||
damaged ^= 1 << epos();
|
||||
int recovered = decode(damaged);
|
||||
assert(recovered == target);
|
||||
}
|
||||
if (1) {
|
||||
// NASA INTRO BCH(15, 5) T=3
|
||||
const int N = 15, K = 5, T = 3, POLY = 0b10100110111;
|
||||
CODE::ShortBCHCodeDecoder<N, K> decode(POLY, T);
|
||||
int target = 0b110010001111010;
|
||||
int damaged = target;
|
||||
typedef std::uniform_int_distribution<int> distribution;
|
||||
auto epos = std::bind(distribution(0, N-1), generator);
|
||||
for (int i = 0; i < T; ++i)
|
||||
damaged ^= 1 << epos();
|
||||
int recovered = decode(damaged);
|
||||
assert(recovered == target);
|
||||
}
|
||||
std::cerr << "Short BCH code decoder test passed!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
40
tests/short_bch_code_encoder_test.cc
Normal file
40
tests/short_bch_code_encoder_test.cc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Test for the short BCH codes encoder
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include "short_bch_code_encoder.hh"
|
||||
|
||||
int main()
|
||||
{
|
||||
if (1) {
|
||||
// Perfect binary Golay code using x^11+x^9+x^7+x^6+x^5+x+1
|
||||
CODE::ShortBCHCodeEncoder<23, 12> encode(0b101011100011);
|
||||
int message = 0b101011011011;
|
||||
int target = 0b10101101101111011111001;
|
||||
int codeword = encode(message);
|
||||
assert(target == codeword);
|
||||
}
|
||||
if (1) {
|
||||
// Perfect binary Golay code using x^11+x^10+x^6+x^5+x^4+x^2+1
|
||||
CODE::ShortBCHCodeEncoder<23, 12> encode(0b110001110101);
|
||||
int message = 0b101011011011;
|
||||
int target = 0b10101101101100100010101;
|
||||
int codeword = encode(message);
|
||||
assert(target == codeword);
|
||||
}
|
||||
if (1) {
|
||||
// NASA INTRO BCH(15, 5) T=3
|
||||
CODE::ShortBCHCodeEncoder<15, 5> encode(0b10100110111);
|
||||
int message = 0b11001;
|
||||
int target = 0b110010001111010;
|
||||
int codeword = encode(message);
|
||||
assert(target == codeword);
|
||||
}
|
||||
std::cerr << "Short BCH code encoder test passed!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
55
tests/short_bch_code_regression_test.cc
Normal file
55
tests/short_bch_code_regression_test.cc
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Regression Test for the short BCH codes encoder and decoder
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "short_bch_code_decoder.hh"
|
||||
#include "short_bch_code_encoder.hh"
|
||||
|
||||
template <int N, int K, int T, int POLY>
|
||||
void bch_test(int trials)
|
||||
{
|
||||
CODE::ShortBCHCodeEncoder<N, K> encode(POLY);
|
||||
CODE::ShortBCHCodeDecoder<N, K> decode(POLY, T);
|
||||
std::random_device rd;
|
||||
typedef std::default_random_engine generator;
|
||||
typedef std::uniform_int_distribution<int> distribution;
|
||||
auto data = std::bind(distribution(0, (1<<K)-1), generator(rd()));
|
||||
auto epos = std::bind(distribution(0, N-1), generator(rd()));
|
||||
while (--trials) {
|
||||
int message = data();
|
||||
int codeword = encode(message);
|
||||
assert((codeword>>(N-K)) == message);
|
||||
int decoded = decode(codeword);
|
||||
assert(decoded == codeword);
|
||||
int damaged = codeword;
|
||||
for (int i = 0; i < T; ++i)
|
||||
damaged ^= 1 << epos();
|
||||
int recovered = decode(damaged);
|
||||
assert(recovered == codeword);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if (1) {
|
||||
// Perfect binary Golay code using x^11+x^9+x^7+x^6+x^5+x+1
|
||||
bch_test<23, 12, 3, 0b101011100011>(1000000);
|
||||
}
|
||||
if (1) {
|
||||
// Perfect binary Golay code using x^11+x^10+x^6+x^5+x^4+x^2+1
|
||||
bch_test<23, 12, 3, 0b110001110101>(1000000);
|
||||
}
|
||||
if (1) {
|
||||
// NASA INTRO BCH(15, 5) T=3
|
||||
bch_test<15, 5, 3, 0b10100110111>(1000000);
|
||||
}
|
||||
std::cerr << "Short BCH code regression test passed!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue