Skip to content

Commit

Permalink
fixes #46 support for bytes input for higher galois fields, thanks to…
Browse files Browse the repository at this point in the history
… another-pjohnson

Signed-off-by: Stephen L. <lrq3000@gmail.com>
  • Loading branch information
lrq3000 committed Dec 9, 2022
1 parent ac78fa0 commit 24359da
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -65,6 +65,9 @@ testsetuppost:
testcoverage:
# This is the preferred way to run the tests since Python 3.10
@+make coverclean
# Build the Cython extension
python setup.py build_ext --inplace
# Run the tests
# nosetests reedsolo --with-coverage --cover-package=reedsolo --cover-erase --cover-min-percentage=80 -d -v
# With PyTest, it is now necessary to first install the python module so that it is found (--cov=<module>)
#python setup.py develop
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -310,7 +310,7 @@ To use the Cython implementation, you need to ``pip install cython`` and a C++ c

Then, use `import RSCodec from creedsolo` instead of importing from the `reedsolo` module, and finally only feed `bytearray()` objects to the `RSCodec` object. Exclusively using bytearrays is one of the reasons creedsolo is faster than reedsolo. You can convert any string by specifying the encoding: `bytearray("Hello World", "UTF-8")`.

Note that there is an inherent limitation of the C implementation which cannot work with higher galois fields than 8 (= characters of max 255 value) because the C implementation only works with bytearrays, and bytearrays only support characters up to 255. If you want to use higher galois fields, you need to use the pure python version, or rewrite the C implementation to use lists instead of bytearrays (which will be MUCH slower so this defeats the purpose and you are better off simply using the pure python version under PyPy).
Note that there is an inherent limitation of the C implementation which cannot work with higher galois fields than 8 (= characters of max 255 value) because the C implementation only works with bytearrays, and bytearrays only support characters up to 255. If you want to use higher galois fields, you need to use the pure python version, which includes a fake `_bytearray` function that overloads the standard bytearray in case galois fields higher than 8 are used to `init_tables()`, or rewrite the C implementation to use lists instead of bytearrays (which will be MUCH slower so this defeats the purpose and you are better off simply using the pure python version under PyPy - an older version of the C implementation was doing just that, and without bytearrays, all performance gains were lost, hence why the bytearrays were kept despite the limitations).

Edge cases
-------------
Expand Down
2 changes: 2 additions & 0 deletions reedsolo.py
Expand Up @@ -276,6 +276,8 @@ def _bytearray(obj = 0, encoding = "latin-1"):
raise(ValueError, "Type of object not recognized!")
elif isinstance(obj, int): # compatibility with list preallocation bytearray(int)
obj = [0] * obj
elif isinstance(obj, bytes):
obj = [int(b) for b in obj]
# Else obj is a list of int, it's ok
return array("i", obj)

Expand Down
7 changes: 7 additions & 0 deletions tests/test_reedsolo.py
Expand Up @@ -281,6 +281,13 @@ def test_multiple_RSCodec(self):
bytearray(rs_256.decode(rs_256.encode(mes))[0])
# At this point, there should not have been any exception raised!

def test_higher_galois_fields_bytes(self):
rs = RSCodec(12, c_exp=12) # same as nsize=4095
str_msg = "This is a message"
bytes_msg = b"This is a binary message"
result = rs.encode(str_msg) # this always worked
result_b = rs.encode(bytes_msg) # this is the dege case that used to fail

class TestGFArithmetics(unittest.TestCase):
'''Test Galois Field arithmetics'''

Expand Down

0 comments on commit 24359da

Please sign in to comment.