Code Monkey home page Code Monkey logo

python-bchlib's Introduction

python-bchlib

This is a python module for encoding, decoding, and correcting data using BCH codes.

Requirements

Python 3.6 or greater required.

Installing the latest release:

$ pip install bchlib

Installing from source:

On Linux, you will need python-dev or equivalent package. Windows, you need Microsoft Visual C++. I've tested this manually using Visual Studio 2015.

$ pip install .

Usage Example

See Python's built-in help import bchlib; help(bchlib) and the module's tests for usage examples.

python-bchlib's People

Contributors

ben-mathews avatar dmopalmer avatar jkent avatar kgwhitmer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-bchlib's Issues

bchlib doesn't export any methods in Python3

Hi, I was trying to build and test this module by running python3 setup.py build and python3 encode-example.py, but it ended up the following error message:

Traceback (most recent call last):
  File "encode-example.py", line 22, in <module>
    ecc = bchlib.bch(ECC_POLY, ECC_BITS)
AttributeError: module 'bchlib' has no attribute 'bch'

I checked out this module in Python3 interactive shell and found no method was exported by bchlib. Lately I found static PyMethodDef module_methods[] in file bchlib.c contains no methods. I don't know if this is the reason why bchlib doesn't export any methods in Python3.

Much appreciated. : )

Python 3.11 compatibility

This package is currently not compatible with Python 3.11.
It fails with the following error message when trying to install using pip install bchlib:

Collecting bchlib
  Using cached bchlib-0.14.0.tar.gz (25 kB)
  Preparing metadata (setup.py) ... done
Building wheels for collected packages: bchlib
  Building wheel for bchlib (setup.py) ... error
  error: subprocess-exited-with-error
  
  × python setup.py bdist_wheel did not run successfully.
  │ exit code: 1
  ╰─> [25 lines of output]
      running bdist_wheel
      running build
      running build_ext
      building 'bchlib' extension
      creating build
      creating build/temp.linux-x86_64-cpython-311
      creating build/temp.linux-x86_64-cpython-311/src
      gcc -pthread -B /home/matz/.conda/envs/bchlib-311/compiler_compat -DNDEBUG -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/matz/.conda/envs/bchlib-311/include -fPIC -O2 -isystem /home/matz/.conda/envs/bchlib-311/include -fPIC -I/home/matz/.conda/envs/bchlib-311/include/python3.11 -c src/bch.c -o build/temp.linux-x86_64-cpython-311/src/bch.o -std=c99
      gcc -pthread -B /home/matz/.conda/envs/bchlib-311/compiler_compat -DNDEBUG -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/matz/.conda/envs/bchlib-311/include -fPIC -O2 -isystem /home/matz/.conda/envs/bchlib-311/include -fPIC -I/home/matz/.conda/envs/bchlib-311/include/python3.11 -c src/bchlib.c -o build/temp.linux-x86_64-cpython-311/src/bchlib.o -std=c99
      src/bchlib.c: In function ‘BCH_encode’:
      src/bchlib.c:144:29: error: lvalue required as left operand of assignment
        144 |         Py_SIZE(result_ecc) = ecc_bytes;
            |                             ^
      src/bchlib.c: In function ‘BCH_decode’:
      src/bchlib.c:226:30: error: lvalue required as left operand of assignment
        226 |         Py_SIZE(result_data) = data.len;
            |                              ^
      src/bchlib.c:234:29: error: lvalue required as left operand of assignment
        234 |         Py_SIZE(result_ecc) = ecc.len;
            |                             ^
      src/bchlib.c: In function ‘BCH_decode_syndromes’:
      src/bchlib.c:421:30: error: lvalue required as left operand of assignment
        421 |         Py_SIZE(result_data) = data.len;
            |                              ^
      error: command '/usr/bin/gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for bchlib
  Running setup.py clean for bchlib
Failed to build bchlib
ERROR: Could not build wheels for bchlib, which is required to install pyproject.toml-based projects

The reason for this is the Py_SIZE is no longer writeable in Python 3.11.

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

 

Failing for (127, 113, t=2) polynomial

I'm trying to use this library to provide the BCH coding used in the TPS data of DVB-T, as per the ETSI spec at https://www.etsi.org/deliver/etsi_en/300700_300799/300744/01.06.02_60/en_300744v010602p.pdf. I'm trying to use the t=2 polynomial x^14 + x^9 + x^8 + x^6 + x^5 + x^4 + x^2 + x + 1 (rendered in binary as 0b100001101110111) with the library, but I keep getting the error RuntimeError: unable to inititalize BCH, bad parameters?. How can I resolve this?

Polynomial.

I have some problems trying to understand the parameters of this algorithm, do you have a source with some examples about the value of polynomial? please.
I am not mathematician and the documentation of wikipedia is very complex for me.

Getting maximum data length

I'm using following code to get maximum possible data length with bch setting:

  • bch.c
        /* sanity check: make sure data length can be handled */
        if (8*len > (bch->n-bch->ecc_bits)) {
                printf("Error: Invalid length: %d %d (%d)\n", len, (bch->n-bch->ecc_bits) / 8, bch->n-bch->ecc_bits);
                return -EINVAL;
        }

Using following code to extract the result:

    data = bytearray(data[:1000])
    ic(len(data), bch.ecc_bytes , bch.ecc_bits, bch.m, bch.n, bch.t )
    ecc = bch.encode(data)

The value 919 (polynominal 8219, bits 64) is not shown in read-only settings:
ic| len(data): 1000
bch.ecc_bytes: 104
bch.ecc_bits: 832
bch.m: 13
bch.n: 8191
bch.t: 64
ic| len(data): 1000, len(ecc): 104
Error: Invalid length: 1000 919 (7359)

It seems it is the value (8191-832) / 8 = 919..

Error when creating BCH(n=127, k=99)

I want to create a code with n=127 and k=99. For this I run the following
bch = bchlib.BCH(128,4)
and then I get segmentation fault!
Am I missing something?

Segmentation fault

Hello @jkent,I use python35 for decoding under Windows10, there is a bug running here" bitflips = bch.decode_inplace(data, ecc)", the bug is "Segmentation fault", hou can I solve it?

nerr

When using my bchlib to my bits, I find nerr = -1, and the correction result is poor. ps: t=6, prim_poly=487

Why are the results different every time?

alyang@CNSHZ-ED-SVR088:/test/python-bchlib-master$ python3.4 encode-example.py
F3 71 5C 51 93 95 6D 8A 75 47 E9 0E 50 10 9E 43 63 22 54 AF 56 8A 38 AB A4 80
alyang@CNSHZ-ED-SVR088:
/test/python-bchlib-master$ python3.4 encode-example.py
63 99 B4 BD DA 54 F3 B1 18 7E D6 20 31 77 AA 57 A3 41 62 2C 27 18 1F 57 59 95
alyang@CNSHZ-ED-SVR088:/test/python-bchlib-master$ python3.4 encode-example.py
EA 86 23 B1 53 02 F9 3A E9 58 AE 11 0F AC 4A 6A 71 A6 F4 73 16 B6 B4 92 18 28
alyang@CNSHZ-ED-SVR088:
/test/python-bchlib-master$

some program question

I'm a new in python.
This is my error below.
How do I solve it?

line 16, in
bch = bchlib.BCH(BCH_POLYNOMIAL, BCH_BITS)
AttributeError: module 'bchlib' has no attribute 'BCH'

Consecutive bch.decode calls lead to wrong output

Using bchlib=1.0.0 & python=3.12, I've found that consecutive calls of bch.decode of the same bch instance results most likely in wrong outputs. Steps to reproduce:

Consecutive bch.decode calls:

>>> from bchlib import BCH
>>> from bitstring import Bits
>>> bch = BCH(t=16, prim_poly=8219)
>>> data = Bits(b"First").tobitarray()
>>> ecc = bch.encode(data)
>>> data2 = Bits(b"Second").tobitarray()
>>> ecc2 = bch.encode(data2)
>>> print(f"n-errors data: {bch.decode(data, ecc)}")
n-errors data: 0
>>> print(f"n-errors data2: {bch.decode(data2, ecc2)}")
n-errors data2: -1

I also added bch.correct in between the decoding steps in case some cleanup would be done there. However, the result is the same.

Same as above, but without the first bch.decode call:

>>> from bchlib import BCH
>>> from bitstring import Bits
>>> bch = BCH(t=16, prim_poly=8219)
>>> data = Bits(b"First").tobitarray()
>>> ecc = bch.encode(data)
>>> data2 = Bits(b"Second").tobitarray()
>>> ecc2 = bch.encode(data2)
>>> # print(f"n-errors data: {bch.decode(data, ecc)}")
>>> print(f"n-errors data2: {bch.decode(data2, ecc2)}")
n-errors data2: 0

Testing this using bchlib=0.14.0 worked fine as expected.

Python2 fails

$ python2 encode-example.py 
Traceback (most recent call last):
  File "encode-example.py", line 5, in <module>
    import bchlib
ImportError: /home/jkent/Projects/gnuc/python-bchlib/bchlib.so: undefined symbol: PyUnicode_AsUTF8

Encoding a piece of data succeeds, decoding throws invalid parameter

When I successfully encode some data, 0-padded to ensure it is format-able as a bytearray, then attempt to decode it, the decode function throws an invalid parameter error.

Although, I haven't been able to decipher what specifically causes the error, I think it has something to do with the choice of input length and not necessarily forcing it to a power of 2. Here I choose the input length to be the smallest possible, k = n - m*t.

Could the decode function be restricted to a power of 2 length input, and if this is the case, why does the encode function accept input that is not a power of 2?

Here is a (somewhat) minimal example:

import bchlib
from bitstring import BitArray
from numpy.random import uniform
//correct 60 errors
bch = bchlib.BCH(8219, 60)
# create random data at smallest allowable length by bch params
data = [0 if uniform() > .5 else 1 for x in range(0, bch.n - bch.m*bch.t)]
bi = BitArray(data)
# 0 pad to full byte
if len(bi) % 8 != 0:
    bi.prepend('0b', + '0' * (8 - (len(bi) % 8)))
by = bytearray(bi)

# encode
parity = bch.encode(by)

# decode throw ValueError: invalid parameters
bch.decode(by, parity)

Thanks!

How to get an (n, k) encoder?

Let's say I want a codeword of length n that can transmit k bits of information.

In particular, I would like to be able to transmit 99 bits of information, codeword length 127 bits, and able to correct 4-bit errors. How should the parameters be set?

RuntimeError: unable to inititalize bch, invalid parameters?

I 've user bchlib before but when trying to use it now (fresh install / other system) I keep getting this error when running:

>> bch = bchlib.BCH(8219, 16)
>> RuntimeError: unable to inititalize bch, invalid parameters?

The numbers dont really matter. I know that I use the lib correctly because I 've used it and the code is the same.

The given example doesn't work

When I try to decode the bytearray using the bch.encode() function, segmentation fault occurs. I've used exactly same things as in your example code. I am working on python 3.6

Installation error

I am getting an installation error and not sure why. I have searched high and low but not able to fix this. Please help.

image

bch.syndromes returning non-zero tuple

I ran following lines in my terminal:

import bchlib
import hashlib
import os
import random

BCH_POLYNOMIAL = 8219
BCH_BITS = 16
bch = bchlib.BCH(BCH_POLYNOMIAL, BCH_BITS)
data = bytearray(os.urandom(512))
ecc = bch.encode(data)
bitflips = bch.decode(data, ecc)

print(bch.syndromes)

Output received :
(1840049368, 32640, 1840049368, 32640, 1821241040, 32640, 1843497928, 32640, 1820922696, 32640, 1843497864, 32640, 1821241040, 32640, 0, 0, 1842967760, 32640, 0, 3000, 1606293634, 772466365, 273, 0, 1840049272, 32640, 1840049272, 32640, 5894240, 0, 4, 0)

Since no changes have been made to data why is it returning a non zero tuple. If the data packets are same there should be a syndrome of len 2*BCH_BITS containg only zeroes ie (0,0,0,0,0,0,....)

BCH Decode of BCH(255,207, t=6) failing

Thank you for providing the Python library!
Our organization uses a shortened form of a (32 bytes (255bits), 26 bytes, t=6) Bose-Chaudhuri-Hocquenghem (BCH) code. The shortened form (250,202) consists of 202 bits of data followed by a 48-bit sextuple error-correcting code ECC to correct up to 6 bit errors in the entire 250 bit message 202 data + 48 ecc). Unfortunately, for all polymonial primative values ECC is more than 48 bits and total message exceeds 255 bits.

We need to detect and correct up to 6 errors in the entire 250-bit pattern (bits 1 through 250 of the message).
Note: For the purpose of error correction, all calculations shall be performed with the full 255 length code. Therefore, 5 zeros are placed before the 202 data bits to form the 207-bit pattern of the (255,207) BCH code. These padding zeros do not affect the generation of the BCH code as described below.
For the (250,202) BCH code, a generator polynomial g(X) (the same as for (255,207) BCH code) is defined as follows:
𝑔(𝑋)=𝐿𝐶𝑀(𝑚1(𝑋),𝑚3(𝑋),𝑚5(𝑋),𝑚7(𝑋),𝑚9(𝑋),𝑚11(𝑋))

For the (250,202) BCH code, a generator polynomial g(X) (the same as for (255,207) BCH code) is defined as follows:
𝑔(𝑋)=𝐿𝐶𝑀(𝑚1(𝑋),𝑚3(𝑋),𝑚5(𝑋),𝑚7(𝑋),𝑚9(𝑋),𝑚11(𝑋))a determination of g(X) results in the following 49-bit binary number
This determines 𝑔(𝑋)=1110001111110101110000101110111110011110010010111.
To generate the BCH code, an information polynomial, m(x) is formed from the 202 data bits as follows:
𝑚(𝑋)=𝑏1𝑋201+𝑏2𝑋200+⋯+𝑏201𝑋+𝑏202

However, using the Python wrapper, we cannot get ECC length less than 56 bits for 6 bit correction. Why is that? Can a new python library be made to increase the stregth?

BCH source code, always error -EBADMSG

Good morning,

First of all, thank you for the great library! It is very well made and simple to use.

I am not really an expert with ecc (and maybe also with C programming) and I am having some problems with the functions in the C src code (I am implementing this lib in an STM32F407). I am replicating the example: I send a message, encode it, make a bitflip on the packet and then decode it and correct the errors. Nevertheless, I always get error -EBADMSG (even if I don't make any bitflip).

I am using a bch with m=9, t=24, generator polynomial = 545, which seems to work fine on the Python side (my data has a size of more or less 30 bytes).

I found out that the function "decode_bch" stops at line 1094 "if (err != nroots)".

The only thing I changed is the function htonl(x), as I don't have "arpa/inet.h", and I swapped it with the macro htonl(x) __bswap32(_x) in "machine/endian.h": might that be the problem, as it is used in encode_bch?

It might also be an input problem: for example, what's the difference between recv_ecc and calc_ecc? I'll paste you here my code where I call encode_bch and decode_bch, too (I debugged to verify the correct copying of the bits and data, ecc are not modified between the encode and the decode).

// ENCODE
void BCH_Encode(uint8_t* data) { // here data is the raw message without ecc
struct bch_control* bch = init_bch(9, 24, (unsigned int) GF9);
uint8_t ecc[bch->ecc_bytes];

encode_bch(bch, data, sizeof(data), ecc);

memcpy(&data[sizeof(data)-1],ecc,(bch->ecc_bytes)*sizeof(uint8_t)); // here i add the ecc to data

}

// DECODE
int BCH_Decode(uint8_t* packet, const unsigned int psize) {

struct bch_control* bch = init_bch(9, 24, (unsigned int) GF9);
unsigned int errloc[24];
uint8_t data[psize-(bch->ecc_bytes)];
uint8_t ecc[bch->ecc_bytes];
unsigned int dsize = sizeof(data);

int err;
printf("%d\n", psize-(bch->ecc_bytes));

bitflips(packet);              // bitflip creation

// separate data and ecc

memcpy(data,packet,(psize-(bch->ecc_bytes))*sizeof(uint8_t));
printf("%s\n", data);

for (int i=0; i<bch->ecc_bytes; i++) {
	ecc[i] = packet[i+dsize];
}

    err = decode_bch(bch, data, dsize, ecc, NULL,  NULL, errloc);

printf("Error: %d\n",err);

if (err != -EBADMSG) {                                 // always have ==
        correct_bch(packet, errloc, psize);
         memmove(data,packet,(psize-(bch->ecc_bytes)));
         memmove(ecc,packet + (psize-(bch->ecc_bytes)-1),(bch->ecc_bytes)*sizeof(uint8_t));

         printf("Message: %s\n", (char*) data);

           memset(packet,'\0',psize);
           memmove(packet,data,psize);
           return 0;
} else {
	return 1; // ERROR_FAILED_DECODE
}

}

Sorry for the long message, I hope I explained clearly my problem. Thank you in advance!

syndrome to error problem

For context, I used n=127, k=64, t=10.
This may not be an issue and on purpose, if so I'm sorry.

When I try to decode a very erroneous code word with more than 10 errors, instead of giving me the error indices that will bring me to the 'closest' code word, errloc is set to an empty tuple (when the output for the decode is negative) and I have no way of finding the mapping to the closest code word.

if that's on purpose, I'd be happy if someone let me know of a way to find the mapping to the closest code words /manipulate syndromes in such a way.
thanks a bunch.

Loop over polynomial combinations

I'm working with some existing code that takes 512 bits and generates a 20 bit BCH syndrome. It looks like the polynomial is either a 1 long value or 4 x 10 bit values.

Is there any try/catch method to loop over polynomials like this:

for poly in range(1,1000):
    try:
        bch = bchlib.BCH(poly, 20)
        print('found')
    except:
        # Do nothing

This unfortunately crashes. Is there any alt way? Thanks!

Getting Runtime error on entering large values for t

If we are providing large values for t say,

bch = bchlib.BCH(2341,1018), we are getting following Runtime error:

RuntimeError: unable to inititalize BCH, bad parameters?
2019-12-04 11:39:52,788 ERROR RuntimeError polynomial:2341 degree of polynomial:11 error bits t:1018
Traceback (most recent call last):
File "", line 25, in

undefined symbol: htobe32

First, thanks for the awesome package!

Versions 0.12.0 and 0.13.0 successfully install...

$ pip install bchlib
Collecting bchlib
  Downloading https://files.pythonhosted.org/packages/8c/a7/940cf5990ba86983abd0df57c20045e6032eb8ce55317eedc35e86b4c863/bchlib-0.13.0-cp37-cp37m-manylinux1_x86_64.whl (55kB)
    100% |████████████████████████████████| 61kB 5.9MB/s 
Installing collected packages: bchlib
Successfully installed bchlib-0.13.0
$

But throw an import error:

$ python3
Python 3.7.3 (default, May 11 2019, 00:38:04) 
[GCC 9.1.1 20190503 (Red Hat 9.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import bchlib
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /opt/bchlib-test/.venv/lib64/python3.7/site-packages/bchlib.cpython-37m-x86_64-linux-gnu.so: undefined symbol: htobe32
>>> 

Seems to have occured in v0.12.0.
v0.10.0 imports ok.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.