From 537aff62a29de6f2797d54355c459084e9f32d56 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Sat, 22 Sep 2018 19:14:10 +0200 Subject: [PATCH] used bitman to help clean up the mess --- bose_chaudhuri_hocquenghem_decoder.hh | 9 ++++---- bose_chaudhuri_hocquenghem_encoder.hh | 31 +++++++++++---------------- tests/bch_decoder_test.cc | 17 ++++++--------- tests/bch_encoder_test.cc | 5 +++-- 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/bose_chaudhuri_hocquenghem_decoder.hh b/bose_chaudhuri_hocquenghem_decoder.hh index 65e95f2..2ab1e13 100644 --- a/bose_chaudhuri_hocquenghem_decoder.hh +++ b/bose_chaudhuri_hocquenghem_decoder.hh @@ -8,6 +8,7 @@ Copyright 2018 Ahmet Inan #define BOSE_CHAUDHURI_HOCQUENGHEM_DECODER_HH #include "reed_solomon_error_correction.hh" +#include "bitman.hh" namespace CODE { @@ -24,11 +25,11 @@ public: { // $syndromes_i = code(pe^{FCR+i})$ for (int i = 0; i < NR; ++i) - syndromes[i] = ValueType((code[0] >> 7) & 1); + syndromes[i] = ValueType(get_be_bit(code, 0)); for (int j = 1; j < N; ++j) { IndexType root(FCR), pe(1); for (int i = 0; i < NR; ++i) { - syndromes[i] = fma(root, syndromes[i], ValueType((code[j / 8] >> (7 - j % 8)) & 1)); + syndromes[i] = fma(root, syndromes[i], ValueType(get_be_bit(code, j))); root *= pe; } } @@ -46,7 +47,7 @@ public: assert(0 <= erasures_count && erasures_count <= NR); if (0) { for (int i = 0; i < erasures_count; ++i) - code[erasures[i] / 8] &= ~(128 >> (erasures[i] % 8)); + set_be_bit(code, erasures[i], 0); } ValueType syndromes[NR]; if (!compute_syndromes(code, syndromes)) @@ -60,7 +61,7 @@ public: if (1 < (int)magnitudes[i]) return -1; for (int i = 0; i < count; ++i) - code[(int)locations[i] / 8] ^= (int)magnitudes[i] << (7 - (int)locations[i] % 8); + xor_be_bit(code, (int)locations[i], (bool)magnitudes[i]); int corrections_count = 0; for (int i = 0; i < count; ++i) corrections_count += !!magnitudes[i]; diff --git a/bose_chaudhuri_hocquenghem_encoder.hh b/bose_chaudhuri_hocquenghem_encoder.hh index 282f02a..33e1106 100644 --- a/bose_chaudhuri_hocquenghem_encoder.hh +++ b/bose_chaudhuri_hocquenghem_encoder.hh @@ -8,6 +8,7 @@ Copyright 2018 Ahmet Inan #define BOSE_CHAUDHURI_HOCQUENGHEM_ENCODER_HH #include +#include "bitman.hh" namespace CODE { @@ -32,12 +33,11 @@ public: --m_degree; assert(generator_degree + m_degree <= NP + 1); for (int i = generator_degree; i >= 0; --i) { - if (!((generator[i/8]>>(i%8))&1)) + if (!get_le_bit(generator, i)) continue; - generator[i/8] &= ~(1<<(i%8)); - generator[i/8] |= (m&1)<<(i%8); + set_le_bit(generator, i, m&1); for (int j = 1; j <= m_degree; ++j) - generator[(i+j)/8] ^= ((m>>j)&1)<<((i+j)%8); + xor_le_bit(generator, i+j, (m>>j)&1); } generator_degree += m_degree; } @@ -45,7 +45,7 @@ public: if (0) { std::cerr << "generator ="; for (int i = 0; i <= NP; ++i) - std::cerr << " " << int((generator[i/8] >> (i%8))&1); + std::cerr << " " << get_le_bit(generator, i); std::cerr << std::endl; } } @@ -53,21 +53,16 @@ public: { // $code = data * x^{NP} + (data * x^{NP}) \mod{generator}$ for (int i = 0; i < NP; ++i) - code[(K+i)/8] &= ~(128>>((K+i)%8)); + set_be_bit(code, K+i, 0); for (int i = 0; i < K; ++i) { - if (((code[i/8]>>(7-i%8))&1) != ((code[K/8]>>(7-K%8))&1)) { - for (int j = 1; j < NP; ++j) { - code[(K+j-1)/8] &= ~(128>>((K+j-1)%8)); - code[(K+j-1)/8] |= (((generator[(NP-j)/8]>>((NP-j)%8))^(code[(K+j)/8]>>(7-(K+j)%8)))&1)<<(7-(K+j-1)%8); - } - code[(N-1)/8] &= ~(128>>((N-1)%8)); - code[(N-1)/8] |= (generator[0]&1)<<(7-(N-1)%8); + if (get_be_bit(code, i) != get_be_bit(code, K)) { + for (int j = 1; j < NP; ++j) + set_be_bit(code, K+j-1, get_le_bit(generator, NP-j) != get_be_bit(code, K+j)); + set_be_bit(code, N-1, get_le_bit(generator, 0)); } else { - for (int j = 1; j < NP; ++j) { - code[(K+j-1)/8] &= ~(128>>((K+j-1)%8)); - code[(K+j-1)/8] |= ((code[(K+j)/8]>>(7-(K+j)%8))&1)<<(7-(K+j-1)%8); - } - code[(N-1)/8] &= ~(128>>((N-1)%8)); + for (int j = 1; j < NP; ++j) + set_be_bit(code, K+j-1, get_be_bit(code, K+j)); + set_be_bit(code, N-1, 0); } } } diff --git a/tests/bch_decoder_test.cc b/tests/bch_decoder_test.cc index 2404870..91b62fd 100644 --- a/tests/bch_decoder_test.cc +++ b/tests/bch_decoder_test.cc @@ -7,6 +7,7 @@ Copyright 2018 Ahmet Inan #include #include #include +#include "bitman.hh" #include "galois_field.hh" #include "bose_chaudhuri_hocquenghem_decoder.hh" @@ -27,10 +28,8 @@ int main() code[i] = target[i]; std::uniform_int_distribution distribution(0, BCH::N-1); auto noise = std::bind(distribution, generator); - for (int i = 0; i < 3; ++i) { - int n = noise(); - code[n / 8] ^= 128 >> (n % 8); - } + for (int i = 0; i < 3; ++i) + CODE::xor_be_bit(code, noise(), 1); decode(code); for (int i = 0; i < L; ++i) assert(code[i] == target[i]); @@ -46,19 +45,17 @@ int main() for (int i = 0; i < L; ++i) target[i] = 0; for (int i = 0, s = 0; i < BCH::K; ++i, s=(s*(s*s*51767+71287)+35149)&0xffffff) - target[i/8] |= ((s^=s>>7)&1) << (7-i%8); + CODE::set_be_bit(target, i, (s^=s>>7)&1); bool parity[BCH::NP] = { 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0 }; for (int i = 0; i < BCH::NP; ++i) - target[(BCH::K+i)/8] |= parity[i] << (7-(BCH::K+i)%8); + CODE::set_be_bit(target, BCH::K+i, parity[i]); uint8_t *code = new uint8_t[L]; for (int i = 0; i < L; ++i) code[i] = target[i]; std::uniform_int_distribution distribution(0, BCH::N-1); auto noise = std::bind(distribution, generator); - for (int i = 0; i < 12; ++i) { - int n = noise(); - code[n / 8] ^= 128 >> (n % 8); - } + for (int i = 0; i < 12; ++i) + CODE::xor_be_bit(code, noise(), 1); (*decode)(code); for (int i = 0; i < L; ++i) assert(code[i] == target[i]); diff --git a/tests/bch_encoder_test.cc b/tests/bch_encoder_test.cc index a6ea9ce..8e303a6 100644 --- a/tests/bch_encoder_test.cc +++ b/tests/bch_encoder_test.cc @@ -6,6 +6,7 @@ Copyright 2018 Ahmet Inan #include #include +#include "bitman.hh" #include "galois_field.hh" #include "bose_chaudhuri_hocquenghem_encoder.hh" @@ -31,13 +32,13 @@ int main() for (int i = 0; i < L; ++i) target[i] = 0; for (int i = 0, s = 0; i < BCH::K; ++i, s=(s*(s*s*51767+71287)+35149)&0xffffff) - target[i/8] |= ((s^=s>>7)&1) << (7-i%8); + CODE::set_be_bit(target, i, (s^=s>>7)&1); uint8_t *code = new uint8_t[L]; for (int i = 0; i < L; ++i) code[i] = target[i]; bool parity[BCH::NP] = { 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0 }; for (int i = 0; i < BCH::NP; ++i) - target[(BCH::K+i)/8] |= parity[i] << (7-(BCH::K+i)%8); + CODE::set_be_bit(target, BCH::K+i, parity[i]); (*encode)(code); for (int i = 0; i < L; ++i) assert(code[i] == target[i]);