python-bchlib
python-bchlib copied to clipboard
BCH Decode of BCH(255,207, t=6) decode_inplace error
Reopening issue which was accidentally closed before resolution.
This succinctly describes the problem. If you add a single binary byte b'\x01' at the beginning to form data byte array, you get a byte array of 26 which successfully encodes the ecc. However, the decode fails and is locked out at 25 bytes on line bitflips = bch.decode_inplace(data, ecc)
It seems to me that if if encodes 26 bytes (201 bits actually with the \x01 prepended), then it should be able to do a bch.decode_inplace(data, ecc) on the data being same 26 bytes ( 201 bits).
To be clearer, this same issue is in the testing branch. Master branch illustrated same issue as testing, adjusting for syntactic changes.
NB: Note data = bytearray(b'\x01'+os.urandom(25)) works going in for the encoder, but fails for the decoder.
import bchlib import hashlib import os import random
def test_bchlib(): # create a bch object BCH_POLYNOMIAL = 285 BCH_BITS = 6 bch = bchlib.BCH(BCH_POLYNOMIAL, BCH_BITS)
# random data data = bytearray(b'\x01'+os.urandom(25)) print(len(data)) # encode and make a "packet" ecc = bch.encode(data) packet = data + ecc
sha1_initial = hashlib.sha1(packet) print('sha1: %s' % (sha1_initial.hexdigest(),)) def bitflip(packet): byte_num = random.randint(0, len(packet) - 1) bit_num = random.randint(0, 7) packet[byte_num] ^= (1 << bit_num) # make BCH_BITS errors for _ in range(BCH_BITS): bitflip(packet) # print hash of packet sha1_corrupt = hashlib.sha1(packet) print('sha1: %s' % (sha1_corrupt.hexdigest(),)) # de-packetize data, ecc = packet[:-bch.ecc_bytes], packet[-bch.ecc_bytes:] print(len(data)) # correct bitflips = bch.decode_inplace(data, ecc) print('bitflips: %d' % (bitflips)) # packetize packet = data + ecc # print hash of packet sha1_corrected = hashlib.sha1(packet) print('sha1: %s' % (sha1_corrected.hexdigest(),)) if sha1_initial.digest() == sha1_corrected.digest(): print('Corrected!') else: print('Failed')if name == "main": test_bchlib()
I propose the bch.c source file line change to allow missed bits in decode sanity check :
/* sanity check: make sure data length can be handled */ if (8*len > (bch->n-bch->ecc_bits))
Change to
/* sanity check: make sure data length can be handled */ if (8*len -1 > (bch->n-bch->ecc_bits))
In the BCHTestCase class in python,
change this max_data_len = bch.n // 8 - (bch.ecc_bits + 7) // 8
to: max_data_len = bch.n // 8 - (bch.ecc_bits + 7) // 8 + 1
Is this still an issue with the v1.0.0 API?