Giter Site home page Giter Site logo

lrq3000 / unireedsolomon Goto Github PK

View Code? Open in Web Editor NEW

This project forked from brownan/reed-solomon

25.0 7.0 18.0 818 KB

Universal errors-and-erasures Reed Solomon codec (error correcting code) in pure Python with extensive documentation

License: MIT License

Python 69.78% Shell 0.04% TeX 7.38% Jupyter Notebook 3.72% Makefile 1.58% Cython 17.50%

unireedsolomon's Introduction

UniReedSolomon

PyPI-Status PyPI-Versions PyPI-Downloads

Build-Status Coverage

UniReedSolomon is a pure-Python universal Reed-Solomon error correction codec with fully documented code and mathematical nomenclatura, compatible with Python 3.7+ and also PyPy 3.

If you are just starting with Reed-Solomon error correction codes, please see the Wikiversity tutorial.

Please also check out the more mature and faster Reedsolo module, a sibling project using a functional oriented approach instead of object oriented, and maintained by one of the co-authors of this project.


For Python 3.7+:

pip install --upgrade unireedsolomon

For Python 2.7 and <= 3.6:

pip install --upgrade unireedsolomon==1.0.5

To install and compile the Cython speed-optimized modules cff.pyx and cpolynomial.pyx, which provide a ~4x speed boost during encoding, install Cython 0.29.x and then type:

pip install --upgrade unireedsolomon --config-setting="--build-option=--cythonize"
>>> import unireedsolomon as rs
>>> coder = rs.RSCoder(20,13)
>>> c = coder.encode("Hello, world!")
>>> print repr(c)
'Hello, world!\x8d\x13\xf4\xf9C\x10\xe5'
>>>
>>> r = "\0"*3 + c[3:]
>>> print repr(r)
'\x00\x00\x00lo, world!\x8d\x13\xf4\xf9C\x10\xe5'
>>>
>>> coder.decode(r)
'Hello, world!'

This library implements a pure-Python documented universal Reed-Solomon error correction codec with a mathematical nomenclatura, compatible with Python 3.7+ and also with PyPy 3.

The project aims to keep a well commented and organized code with an extensive documentation and mathematical clarity of the various arithmetic operations.

How does this library differs from other Reed-Solomon libraries?

  • universal: compatibility with (almost) any other Reed-Solomon codec. This means that you can choose the parameters so that you can either encode data and decode it with another RS codec, or on the opposite encode data with another RS codec and decode this data with this library.
  • errors-and-erasures decoding allows to decode both erasures (where you know the position of the corrupted characters) and errors (where you don't know where are the corrupted characters) at the same time (because you can decode more erasures than errors, so if you can provide even a few know corrupted characters positions, this can help a lot the decoder to repair the message).
  • documented: following literate programming guidelines, you should understand everything you need about RS by reading the code and the comments.
  • mathematical nomenclatura: for example, contrary to most other RS libraries, you will see a clear distinction between the different mathematical constructs, such as the Galois Fields numbers are clearly separated from the generic Polynomial objects, and both are separated from the Reed-Solomon algorithm, which makes use of both of those constructs. For this purpose, object-oriented programming was chosen to design the architecture of the library, although obviously at the expense of a bit of performance. However, this library favors mathematical clarity and documentation over performance (even if performance is optimized whenever possible).
  • pure-Python means that there are no dependencies whatsoever apart from the Python interpreter. This means that this library should be resilient in the future (since it doesn't depend on external libraries who can become broken with time, see software rot), and you can use it on any system where Python can be installed (including online cloud services).

The authors tried their best to extensively document the algorithms. However, a lot of the math involved is non-trivial and we can't explain it all in the comments. To learn more about the algorithms, see these resources:

Also, here's a copy of the presentation one of the authors gave to the class Spring 2010 on his experience implementing this library. The LaTeX source is in the presentation directory.

http://www.cs.duke.edu/courses/spring10/cps296.3/decoding_rs.pdf

The code was lately updated to support errors-and-erasures decoding (both at the same time), and to be universal (you can supply the parameters to be compatible with almost any other RS codec).

The codec has decent performances if you use PyPy with the fast methods (~1 MB/s), but it would be faster if we drop the object-oriented design (implementing everything in functions), but this would be at the expense of mathematical clarity. If you are interested, see the reedsolo library by Tomer Filiba, which is exactly the same implementation but only functional without objects (results in about 5x speedup).

rs.py
Holds the Reed-Solomon Encoder/Decoder object
polynomial.py
Contains the Polynomial object (pure-python)
ff.py
Contains the GF2int object representing an element of the GF(2^p) field, with p being 8 by default (pure-python)
polynomial.pyx
Cython implementation of polynomial.py with equivalent functions (optional)
ff.pyx
Cython implementation of ff.py with equivalent functions (optional)
unireedsolomon.rs.RSCoder(n, k, generator=3, prim=0x11b, fcr=1, c_exp=8)

Creates a new Reed-Solomon Encoder/Decoder object configured with the given n and k values. n is the length of a codeword, must be less than 256 k is the length of the message, must be less than n generator, prim and fcr parametrize the Galois Field that will be built c_exp is the Galois Field range (ie, 8 means GF(2^8) = GF(256)), which is both the limit for one symbol's value, and the maximum length of a message+ecc.

The code will have error correcting power (ie, maximum number of repairable symbols) of 2*e+v <= (n-k), where e is the number of errors and v the number of erasures.

The typical RSCoder is RSCoder(255, 223)

RSCoder.encode(message, poly=False, k=None)

Encode a given string with reed-solomon encoding. Returns a byte string with the k message bytes and n-k parity bytes at the end.

If a message is < k bytes long, it is assumed to be padded at the front with null bytes (ie, a shortened Reed-Solomon code).

The sequence returned is always n bytes long.

If poly is not False, returns the encoded Polynomial object instead of the polynomial translated back to a string (useful for debugging)

You can change the length (number) of parity/ecc bytes at encoding by setting k to any value between [1, n-1]. This allows to create only one RSCoder and then use it with a variable redundancy rate.

RSCoder.encode_fast(message, poly=False, k=None)
Same as encode() but using faster algorithms and optimization tricks.
RSCoder.decode(message_ecc, nostrip=False, k=None, erasures_pos=None, only_erasures=False):

Given a received string or byte array message_ecc (composed of a message string + ecc symbols at the end), attempts to decode it. If it's a valid codeword, or if there are no more than 2*e+v <= (n-k) erratas (called the Singleton bound), the message is returned.

You can provide the erasures positions as a list to erasures_pos. For example, if you have "hella warld" and you know that a is an erasure, you can provide the list erasures_pos=[4, 7]. You can correct twice as many erasures than errors, and if some provided erasures are wrong (they are correct symbols), then there's no problem, they will be repaired just fine (but will count towards the Singleton bound). You can also specify that you are sure there are only erasures and no errors at all by setting only_erasures=True.

A message always has k bytes, if a message contained less it is left padded with null bytes (punctured RS code). When decoded, these leading null bytes are stripped, but that can cause problems if decoding binary data. When nostrip is True, messages returned are always k bytes long. This is useful to make sure no data is lost when decoding binary data.

Note that RS can correct errors both in the message and the ecc symbols.

RSCoder.decode_fast(message_ecc, nostrip=False, k=None, erasures_pos=None, only_erasures=False):
Same as decode() but using faster algorithms and optimization tricks.
RSCoder.check(message_ecc, k=None)
Verifies the codeword (message + ecc symbols at the end) is valid by testing that the code as a polynomial code divides g, or that the syndrome is all 0 coefficients. The result is not foolproof: if it's False, you're sure the message was corrupted (or that you used the wrong RS parameters), but if it's True, it's either that the message is correct, or that there are too many errors (ie, more than the Singleton bound) for RS to do anything about it. returns True/False
RSCoder.check_fast(message_ecc, k=None)
Same as check() but using faster algorithms and optimization tricks.
unireedsolomon.ff.find_prime_polynomials(generator=2, c_exp=8, fast_primes=False, single=False)
Compute the list of prime polynomials for the given generator and galois field characteristic exponent. You can then use this prime polynomial to specify the mandatory "prim" parameter, particularly if you are using a larger Galois Field (eg, 2^16).

Besides the main RSCoder object, two other objects are used in this implementation: Polynomial and GF2int. Their use is not specifically tied to the coder or even to the Reed-Solomon algorithm, they are just generic mathematical constructs respectively representing polynomials and Galois field's number of base 2.

You do not need to know about the internal API to use the RS codec, this is just left as a documentation for the reader interested into dwelling inside the mathematical constructs.

polynomial.Polynomial(coefficients=[], **sparse)

There are three ways to initialize a Polynomial object. 1) With a list, tuple, or other iterable, creates a polynomial using the items as coefficients in order of decreasing power

2) With keyword arguments such as for example x3=5, sets the coefficient of x^3 to be 5

3) With no arguments, creates an empty polynomial, equivalent to Polynomial([0])

>>> print Polynomial([5, 0, 0, 0, 0, 0])
5x^5
>>> print Polynomial(x32=5, x64=8)
8x^64 + 5x^32
>>> print Polynomial(x5=5, x9=4, x0=2)
4x^9 + 5x^5 + 2

Polynomial objects export the following standard functions that perform the expected operations using polynomial arithmetic. Arithmetic of the coefficients is determined by the type passed in, so integers or GF2int objects could be used, the Polynomial class is agnostic to the type of the coefficients.

__add__
__divmod__
__eq__
__floordiv__
__hash__
__len__
__mod__
__mul__
__ne__
__neg__
__sub__
evaluate(x)
degree()
    Returns the degree of the polynomial
get_coefficient(degree)
    Returns the coefficient of the specified term
ff.GF2int(value)

Instances of this object are elements of the field GF(2^p) and instances are integers in the range 0 to (2^p)-1. By default, the field is GF(2^8) and instances are integers in the range 0 to 255 and is defined using the irreducable polynomial 0x11b or in binary form: x^8 + x^4 + x^3 + x + 1 and using 3 as the generator for the exponent table and log table.

You can however use other parameters for the Galois Field, using the init_lut() function.

ff.find_prime_polynomials(generator=2, c_exp=8, fast_primes=False, single=False)
Find the list of prime polynomials to use to generate the look-up tables for your field.
ff.init_lut(generator=3, prim=0x11b, c_exp=8)
Generate the look-up tables given the parameters. This effectively parametrize your Galois Field (ie, generator=2, prim=0x1002d, c_exp=16) will generate a GF(2^16) field.

The GF2int class inherits from int and supports all the usual integer operations. The following methods are overridden for arithmetic in the finite field GF(2^p)

__add__
__div__
__mul__
__neg__
__pow__
__radd__
__rdiv__
__rmul__
__rsub__
__sub__
inverse()
    Multiplicative inverse in GF(2^p)

Although sanity checks are implemented whenever possible and when they are not too much resource consuming, there are a few cases where messages will not be decoded correctly without raising an exception:

  • If an incorrect erasure location is provided, the decoding algorithm will just trust the provided locations and create a syndrome that will be wrong, resulting in an incorrect decoded message. In case reliability is critical, always use the check() method after decoding to check the decoding did not go wrong.
  • Reed-Solomon algorithm is limited by the Singleton Bound, which limits not only its capacity to correct errors and erasures relatively to the number of error correction symbols, but also its ability to check if the message can be decoded or not. Indeed, if the number of errors and erasures are greater than the Singleton Bound, the decoder has no way to mathematically know for sure whether there is an error at all, it may very well be a valid message (although not the message you expect, but mathematically valid nevertheless). Hence, when the message is tampered beyond the Singleton Bound, the decoder may raise an exception, but it may also return a mathematically valid but still tampered message. Using the check() method cannot fix that either. To work around this issue, a solution is to use parity or hashing functions in parallel to the Reed-Solomon codec: use the Reed-Solomon codec to repair messages, use the parity or hashing function to check if there is any error. Due to how parity and hashing functions work, they are much less likely to produce a false negative than the Reed-Solomon algorithm. This is a general rule: error correction codes are efficient at correcting messages but not at detecting errors, hashing and parity functions are the adequate tool for this purpose.

imageencode.py is an example script that encodes codewords as rows in an image. It requires PIL to run.

Usage: python imageencode.py [-d] <image file>

Without the -d flag, imageencode.py will encode text from standard in and output it to the image file. With -d, imageencode.py will read in the data from the image and output to standard out the decoded text.

An example is included: exampleimage.png. Try decoding it as-is, then open it up in an image editor and paint some vertical stripes on it. As long as no more than 16 pixels per row are disturbed, the text will be decoded correctly. Then draw more stripes such that more than 16 pixels per row are disturbed and verify that the message is decoded improperly.

Notice how the parity data looks different--the last 32 pixels of each row are colored differently. That's because this particular image contains encoded ASCII text, which generally only has bytes from a small range (the alphabet and printable punctuation). The parity data, however, is binary and contains bytes from the full range 0-255. Also note that either the data area or the parity area (or both!) can be disturbed as long as no more than 16 bytes per row are disturbed.

If either a C compiler or Cython is found, rs.py will automatically load the Cython implementations (the *.pyx files). These are provided as optimized versions of the pure-python implementations, with equivalent functionalities. The goal was to get a speedup, which is the case, but using PyPy on the pure-python implementation provides a significantly higher speedup than the Cython implementation. The Cython implementations are still provided for the interested reader, but the casual user is not advised to use them. If you want to encode and decode fast, use PyPy.

  • Several academic publications used unireedsolomon, see this list.
  • "Reed-Solomon codes for coders", free practical beginner's tutorial with Python code examples on WikiVersity. Partially written by one of the authors of the present software.
  • "Algebraic codes for data transmission", Blahut, Richard E., 2003, Cambridge university press. Readable online on Google Books. This book was pivotal in helping to understand the intricacies of the universal Berlekamp-Massey algorithm (see figures 7.5 and 7.10).

Written from scratch by Andrew Brown <[email protected]> <[email protected]> (c) 2010.

Upgraded and maintained by Stephen Karl Larroque <[email protected]> in 2015-2020.

Licensed under the MIT License.

unireedsolomon's People

Contributors

adirio avatar brownan avatar lrq3000 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

unireedsolomon's Issues

Fast primes not Python 3 compatible

Python version 3.x:

import unireedsolomon
unireedsolomon.find_prime_polynomials(fast_primes=True)

raises the following error:

Traceback (most recent call last):
  File "...", line 2963, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-1e4baa4603d9>", line 1, in <module>
    unireedsolomon.find_prime_polynomials(fast_primes=True)
  File ".../unireedsolomon/unireedsolomon/ff.py", line 90, in find_prime_polynomials
    prim_candidates = rwh_primes1(field_charac_next) # generate maybe prime polynomials and check later if they really are irreducible
  File ".../unireedsolomon/unireedsolomon/ff.py", line 63, in rwh_primes1
    sieve = [True] * (n/2)
TypeError: can't multiply sequence by non-int of type 'float'

The error is due to the / operator change between Python 2 and 3, where / is no longer the integer division. // is interpreted as integer division in both versions of Python so there is an easy replacement.

can't install with python3.7

Hi, somehow i cant install this via pip. I've tried it via the git repo as well as directly via pip install unireedsolomon with either python 3.7 64 bit and 32 bit.
I installed python version 3.6 64 bit and it installs successfully.
Is there a problem with my python 3.7 version ? Or is there another way to get this working with python version 3.7?

return number of repaired errors

Hi,

Would it be possible to not only return the data but also the number of repaired errors?
That way, for example a communication-channel can switch to a lower bitrate if errors are detected.

Fail to decode with erasures but no exception/error given

Hi,
I like this library a lot however I encountered a strange behaviour that seems like a bug to me. When doing a decode with erasures I get the same corrupted message back without any error given. This happens even when the check function detects errors. My guess is that the one false erasure somehow messes it up but I read that it should be safe to supply false erasures (they just use up one RSCode)

Lets look at the code:

import unireedsolomon as rs
OrigMsg =      bytearray(bytes([0x83, 0x1F, 0x00, 0x00, 0xFF, 0x00, 0X93, 0xA8, 0x00]))
CorruptedMsg = bytearray(bytes([0x83, 0x10, 0x00, 0x01, 0xFF, 0x01, 0X93, 0xA8, 0x00]))
coder = rs.RSCoder(24, 20)
messageDataAndRSCodeWithNullBytes = coder.encode(OrigMsg, return_string=False)
# Add the RSCodes from OrigMsg to the corrupted message
corruptedMsgWithRSCodes = CorruptedMsg + bytearray(messageDataAndRSCodeWithNullBytes[-4:])
paddedCorruptedMsgWithRSCodes = bytearray(bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) + corruptedMsgWithRSCodes
print("PaddedCorruptedMsgWithRSCodes: " + str(paddedCorruptedMsgWithRSCodes))
try:
	coder.decode(paddedCorruptedMsgWithRSCodes)
except:
	print('As expected decoding fails due to too many errors (4 RSCodes, and 3 errors)')

if not coder.check(paddedCorruptedMsgWithRSCodes):
	print('As expected check fails')

try:
	decodedMsgAndCodeTuple = coder.decode(paddedCorruptedMsgWithRSCodes, erasures_pos=[11,12])
	decodedMsgAndCode = bytearray((decodedMsgAndCodeTuple[0] + decodedMsgAndCodeTuple[1]).encode('latin-1'))
	print('Decoding didnt throw error when we point to one correct erasure (position 12) and one wrong erasure (position 11) [why?]')
	if decodedMsgAndCode == corruptedMsgWithRSCodes:
		print('The message was not decoded, the corrupted message is returned without anything fixed, and no error given [why?]')
		
	if not coder.check(bytearray(bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) + decodedMsgAndCode):
		print('Check detects the error of course (since it same message that we checked before)')
except:
	print('decoding failed, this is what I expected')

The prints of this is:

PaddedCorruptedMsgWithRSCodes: bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83\x10\x00\x01\xff\x01\x93\xa8\x006\x91\xbay')
As expected decoding fails due to too many errors (4 RSCodes, and 3 errors)
As expected check fails
Decoding didnt throw error when we point to one correct erasure (position 12) and one wrong erasure (position 11) [why?]
The message was not decoded, the corrupted message is returned without anything fixed, and no error given [why?]
Check detects the error of course (since it same message that we checked before)

Am I wrong in assuming this is a bug? Any idea why it behaves this way?

decode_fast fails with RS(255,247) with 4 errors, when it should not

This is with unireedsolomon 1.0 via pip install unireedsolomon. The decode_fast() function seems to fail when it shouldn't. I've gotten failures with 4 errors for (255,247) and 8 errors for (255,239).

(And for the record, it doesn't seem faster than decode() at least not for (255,247) and (255,239). edit: oh, never mind, I wasn't timing it carefully enough. Just ran it on (255,191) with 32 errors and for 500 iterations it took 8 seconds for decode_fast() and 36 seconds for decode(). For (255,223) with 16 errors: 500 iterations took 4 seconds for decode_fast() and about 8 seconds for decode(). For (255,239) with 8 errors: 500 iterations took 1.9 seconds for decode_fast()and 2.9 seconds fordecode()`)

Python code:

import unireedsolomon as rs

decoder = rs.RSCoder(255,247,generator=2,prim=0x11d,fcr=0,c_exp=8)
e = [0]*255
e[68] = 4
e[150] = 128
e[181] = 1
e[184] = 16
print "Using decoder.decode():"
print decoder.decode(e)
print "Using decoder.decode_fast():"
print decoder.decode_fast(e)

Result:

Using decoder.decode():
('', '\x00')
Using decoder.decode_fast():
---------------------------------------------------------------------------
RSCodecError                              Traceback (most recent call last)
<ipython-input-9-d8a8a6fc239f> in <module>()
     11 print decoder.decode(e)
     12 print "Using decoder.decode_fast():"
---> 13 print decoder.decode_fast(e)

/Users/jmsachs/anaconda/lib/python2.7/site-packages/unireedsolomon/rs.pyc in decode_fast(self, r, nostrip, k, erasures_pos, only_erasures, return_string)
    439         # being the rightmost byte
    440         # X is a corresponding array of GF(2^8) values where X_i = alpha^(j_i)
--> 441         X, j = self._chien_search_faster(sigma)
    442 
    443         # Sanity check: Cannot guarantee correct decoding of more than n-k errata (Singleton Bound, n-k being the minimum distance), and we cannot even check if it's correct (the syndrome will always be all 0 if we try to decode above the bound), thus it's better to just return the input as-is.

/Users/jmsachs/anaconda/lib/python2.7/site-packages/unireedsolomon/rs.pyc in _chien_search_faster(self, sigma)
    884         if len(j) != errs_nb:
    885             # Note: decoding messages+ecc with length n > self.gf2_charac does work partially, but it's wrong, because you will get duplicated values, and then Chien Search cannot discriminate which root is correct and which is not. The duplication of values is normally prevented by the prime polynomial reduction when generating the field (see init_lut() in ff.py), but if you overflow the field, you have no guarantee anymore. We may try to use a bruteforce approach: the correct positions ARE in the final array j, but the problem is because we are above the Galois Field's range, there is a wraparound because of overflow so that for example if j should be [0, 1, 2, 3], we will also get [255, 256, 257, 258] (because 258 % 255 == 3, same for the other values), so we can't discriminate. The issue with that bruteforce approach is that fixing any errs_nb errors among those will always give a correct output message (in the sense that the syndrome will be all 0), so we may not even be able to check if that's correct or not, so there's clearly no way to decode a message of greater length than the field.
--> 886             raise RSCodecError("Too many (or few) errors found by Chien Search for the errata locator polynomial!")
    887 
    888         return X, j

RSCodecError: Too many (or few) errors found by Chien Search for the errata locator polynomial!

Implement fast matrix encoding

Use BackBlaze tutorial and sourcecode as a reference for block encoding (ie, encoding blocks = rows of characters) using fast matrix multiplication. Not only will we encode blocks of characters, which will significantly speedup the process, but also doing matrix multiplication will provide a huge additional speed boost, using specialized linear algebra libraries.

The only thing I don't understand is how the init table is generated with this approach.

Bitwise parities instead of byte ?

I would like to know whether there's a possibility of having bitwise parities instead of bytes appended in the end. Is it something to do with the assignment of Galois Fields in this particular package ?

For example, I used matlab comm.RSEncoder and there I merely need to put the N, K and prim_poly values and the coder can simply give me a codelength depending upon the N and prim_poly. I am actually skeptical about how to use this very functionality here in python. Can you please give me a short example how to implement proper parameters if I wish to have a RS code (7,3) with each symbol having 3 bits only.

rs.RSCoder failed if n = 255 and k = 255

coder = rs.RSCoder(255, 255)
code = coder.encode(data, False, None, True)

If codeword and message length are 255, it is failing with error -

Codeword length n must be greater than message length k

does not decode list correctly in python 3

am using python3 3.8.3 and data in bytes form and always raises unireedsolomon.rs.RSCodecError: Too many (or few) errors found by Chien Search for the errata locator polynomial!, have to decode to string(got package from pip)
even if data is fully correct

Add __version__ as per PEP396

I have a bug to report, and went to check the package's __version__, but there is none.

I do see it (1.0) in setup.py.

Could you please add __version__ as per PEP396 (and PEP8)?

I am tempted to volunteer to put together a PR, based on one of the answers https://stackoverflow.com/questions/2058802/how-can-i-get-the-version-defined-in-setup-py-setuptools-in-my-package -- but I'm very inexperienced in package maintenance and am not sure of the most reasonable way to do it, or how to test it.

Error with `ascii` codec during installation from sources

Hello!

I have a problem during installation from release sources v1.0.2.

The error message is:

Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-b74qszba/unireedsolomon/setup.py", line 51, in <module>
        long_description = open("README.rst", "r").read(),
      File "/usr/lib/python3.6/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 3471: ordinal not in range(128)

I found that README.rst contains the only utf-8 encoded symbol '–'. It is between Reed and Solomon:

* `<http://en.wikipedia.org/wiki/Reed–Solomon_error_correction>`_

Is it a typo or I should find another way to fix the problem?

Thank you in advance.

Output bytes instead of str in Python 3

In Python 2, we needed to use str if we wanted to work with bytes. Python 3 has a native bytes type, and str is meant to be an abstract representation for text.

Support n>256

I'm looking for a reed-solomon encoder which can handle n>256. Could you add this feature?

Why is this limitation present to begin with?

GF2int is a a global singleton and does not allow multiple RSCoder instances with different field generator polynomials.

GF2int is a a global singleton and does not allow multiple RSCoder instances with different field generator polynomials.

import unireedsolomon as rs

def codeword_symbols(msg):
    return [ord(c) for c in msg]

def find_generator(rscoder):
    """ Returns the generator polynomial of an RSCoder class """
    msg = [0]*(rscoder.k - 1) + [1]
    degree = rscoder.n - rscoder.k
    codeword = rscoder.encode(msg)
    # look at the trailing elements of the codeword
    return codeword_symbols(codeword[(-degree-1):])

rs4 = rs.RSCoder(15,11,generator=2,prim=0x13,fcr=0,c_exp=4)
print "g4(x) = %s" % find_generator(rs4)
encmsg15 = codeword_symbols(rs4.encode([1,2,3,4,5,6,7,8,9,10,11]))
print "RS(15,11) encoded example message from BBC WHP031:\n", encmsg15

rs8 = rs.RSCoder(255,239,generator=2,prim=0x11d,fcr=0,c_exp=8)
print "g8(x) = %s" % find_generator(rs8)
encmsg15 = codeword_symbols(rs4.encode([1,2,3,4,5,6,7,8,9,10,11]))
print "RS(15,11) encoded example message from BBC WHP031:\n", encmsg15
rs4 = rs.RSCoder(15,11,generator=2,prim=0x13,fcr=0,c_exp=4)
encmsg15 = codeword_symbols(rs4.encode([1,2,3,4,5,6,7,8,9,10,11]))
print "RS(15,11) encoded example message from BBC WHP031:\n", encmsg15

results in:

g4(x) = [1, 15, 3, 1, 12]
RS(15,11) encoded example message from BBC WHP031:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 3, 12, 12]
g8(x) = [1, 59, 13, 104, 189, 68, 209, 30, 8, 163, 65, 41, 229, 98, 50, 36, 59]
RS(15,11) encoded example message from BBC WHP031:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 187, 6, 230, 91]
RS(15,11) encoded example message from BBC WHP031:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 3, 12, 12]

attempted relative import

" File "...p\unireedsolomon-master\unireedsolomon\imageencode.py", line 4, in
from . import rs
ImportError: attempted relative import with no known parent package" while trying to run imageencode

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.