Skip to main content

Pythonic universal errors-and-erasures Reed-Solomon codec to protect your data from errors and bitrot, with a future-proof zero-dependencies pure-python implementation and an optional speed-optimized Cython/C extension.

Project description

PyPI-Status PyPI-Versions PyPI-Downloads

Build-Status Coverage

Conda-Forge-Status Conda-Forge-Platforms Conda-Forge-Downloads

⏳🛡 Pythonic universal errors-and-erasures Reed-Solomon encoder/decoder codec to protect your data from errors and bitrot. Includes a future-proof zero-dependencies pure-python implementation 🔮 as well as an optional speed-optimized Cython/C extension 🚀

This is a burst-type implementation, so that it supports any Galois field higher than 2^3, but not binary streams. Burst errors are non-random errors that more often happen on data storage mediums such as hard drives, hence this library is better suited for data storage protection, and less for streams noise correction, although it also works for this purpose but with a bit of overhead (since it works with bytes only, instead of bits).

Based on the wonderful tutorial at Wikiversity, written by “Bobmath” and “LRQ3000”. If you are just starting with Reed-Solomon error correction codes, the Wikiversity article is a good beginner’s introduction.


Installation

For the latest stable release (compatible with Python >= 3.7), install with:

pip install --upgrade reedsolo

For the latest development release, use:

pip install --upgrade reedsolo --pre

For the cutting-edge code (likely unstable, do not use in production!), use:

pip install --upgrade git+https://github.com/tomerfiliba-org/reedsolomon

If you have some issues installing through pip, maybe this command may help, by forcing the use of sdist instead of wheels:

pip install reedsolo --no-binary="reedsolo" --no-cache

Note: for Python 2.7 and Python <= 3.6, please use v1.7.0:

pip install --upgrade reedsolo==1.7.0

Through wheels/pip, a pure-python implementation called reedsolo is installed, and for platforms supported by cibuildwheel, a precompiled speed-optimized creedsolo module is included. For other platforms or to compile from source (this requires cython>=3.0.0b2 and a C compiler), a build option can be specified:

# To compile from the latest stable release:
pip install --upgrade reedsolo --no-binary "reedsolo" --no-cache --config-setting="--build-option=--cythonize" --use-pep517 --isolated --verbose
# To compile from the latest development release:
pip install --upgrade reedsolo --no-binary "reedsolo" --no-cache --config-setting="--build-option=--cythonize" --use-pep517 --isolated --pre --verbose
# To compile from the cutting edge code:
pip install --upgrade "reedsolo @ git+https://github.com/tomerfiliba-org/reedsolomon" --no-binary "reedsolo" --no-cache --config-setting="--build-option=--cythonize" --use-pep517 --isolated --pre --verbose

The --config-setting="--build-option=--cythonize" flag signals to the setuptools backend to propagate to reedsolo's setup.py to build the optional cythonized extension. The --no-binary "reedsolo" and --no-cache options are necessary since pip 23.1 to force the use of the sdist instead of wheels.

or locally with:

pip install --upgrade . --config-setting="--build-option=--cythonize" --verbose

Note: for development, it’s possible to add the --editable flag to use the local folder without installing in site-packages, and use .[test] instead of . to install all required packages to test this module locally.

The package for the development or cutting-edge releases can also be built locally with the pep517 compliant build tool:

pip install build
# With cythonization (from *.pyx to *.c to *.pyd)
python -sBm build --config-setting="--build-option=--cythonize"
# or skip cythonization and only compile from the already transpiled c extension (from *.c to *.pyd)
python -sBm build --config-setting="--build-option=--native-compile"

The setup.py will then try to build the Cython optimized module creedsolo.pyx if Cython is installed, which can then be imported as import creedsolo instead of import reedsolo, with the same features between both modules. Note: Make sure to use --config-setting singular, because build does not (yet) recognize the plural form contrary to pip.

As an alternative, use conda to install a compiled version for various platforms:

conda install -c conda-forge reedsolo

Various Linux distributions builds are also available, thanks to a network of amazing maintainers:

Package for Gentoo Linux, thanks to maintainer Michał Górny! Package for Debian Linux, thanks to maintainer Faidon Liambotis! Package for Fedora Linux, thanks to maintainer belegdol! Package for Arch Linux, thanks to maintainer Jelle van der Waa! Package for Alpine Linux, thanks to maintainer Michał Polański! Package for ALT Linux, thanks to maintainer Sergey Bolshakov! List of packages for other Linux distributions

Usage

Basic usage with high-level RSCodec class

# Initialization >>> from reedsolo import RSCodec, ReedSolomonError >>> rsc = RSCodec(10) # 10 ecc symbols

# Encoding # just a list of numbers/symbols: >>> rsc.encode([1,2,3,4]) b’x01x02x03x04,x9dx1c+=xf8hxfax98M’ # bytearrays are accepted and the output will be matched: >>> rsc.encode(bytearray([1,2,3,4])) bytearray(b’x01x02x03x04,x9dx1c+=xf8hxfax98M’) # encoding a byte string is as easy: >>> rsc.encode(b’hello world’) b’hello worldxed%Txc4xfdxfdx89xf3xa8xaa’

Note: strings of any length, even if longer than the Galois field, will be encoded as well using transparent chunking.

Note2: it is strongly recommended to always use bytearrays. Using encoded strings is accepted by the RSCodec API, as a convenient facility for neophytes, but encodings such as UTF-8 have variable lengths, so internally the module has to convert to a bytearray. If you just want to protect a string, you do not need to use a bytearray, but if you need to store or send the protected data in a fixed size field, such as in a binary file or a data stream, use a bytearray.

# Decoding (repairing) >>> rsc.decode(b’hello worldxed%Txc4xfdxfdx89xf3xa8xaa’)[0] # original b’hello world’ >>> rsc.decode(b’heXlo worXdxed%Txc4xfdXx89xf3xa8xaa’)[0] # 3 errors b’hello world’ >>> rsc.decode(b’hXXXo worXdxed%Txc4xfdXx89xf3xa8xaa’)[0] # 5 errors b’hello world’ >>> rsc.decode(b’hXXXo worXdxed%Txc4xfdXXxf3xa8xaa’)[0] # 6 errors - fail Traceback (most recent call last): … reedsolo.ReedSolomonError: Too many (or few) errors found by Chien Search for the errata locator polynomial!

Important upgrade notice for pre-1.0 users: Note that RSCodec.decode() returns 3 variables:

  1. the decoded (corrected) message

  2. the decoded message and error correction code (which is itself also corrected)

  3. and the list of positions of the errata (errors and erasures)

Here is how to use these outputs:

>>> tampered_msg = b'heXlo worXd\xed%T\xc4\xfdX\x89\xf3\xa8\xaa'
>>> decoded_msg, decoded_msgecc, errata_pos = rsc.decode(tampered_msg)
>>> print(decoded_msg)  # decoded/corrected message
bytearray(b'hello world')
>>> print(decoded_msgecc)  # decoded/corrected message and ecc symbols
bytearray(b'hello world\xed%T\xc4\xfd\xfd\x89\xf3\xa8\xaa')
>>> print(errata_pos)  # errata_pos is returned as a bytearray, hardly intelligible
bytearray(b'\x10\t\x02')
>>> print(list(errata_pos))  # convert to a list to get the errata positions as integer indices
[16, 9, 2]

Since we failed to decode with 6 errors with a codec set with 10 error correction code (ecc) symbols, let’s try to use a bigger codec, with 12 ecc symbols.

>>> rsc = RSCodec(12)  # using 2 more ecc symbols (to correct max 6 errors or 12 erasures)
>>> rsc.encode(b'hello world')
b'hello world?Ay\xb2\xbc\xdc\x01q\xb9\xe3\xe2='
>>> rsc.decode(b'hello worXXXXy\xb2XX\x01q\xb9\xe3\xe2=')[0]         # 6 errors - ok, but any more would fail
b'hello world'
>>> rsc.decode(b'helXXXXXXXXXXy\xb2XX\x01q\xb9\xe3\xe2=', erase_pos=[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16])[0]  # 12 erasures - OK
b'hello world'

This shows that we can decode twice as many erasures (where we provide the location of errors ourselves) than errors (with unknown locations). This is the cost of error correction compared to erasure correction.

To get the maximum number of errors or erasures that can be independently corrected (ie, not simultaneously):

>>> maxerrors, maxerasures = rsc.maxerrata(verbose=True)
This codec can correct up to 6 errors and 12 erasures independently
>>> print(maxerrors, maxerasures)
6 12

To get the maximum number of errors and erasures that can be simultaneously corrected, you need to specify the number of errors or erasures you expect:

>>> maxerrors, maxerasures = rsc.maxerrata(erasures=6, verbose=True)  # we know the number of erasures, will calculate how many errors we can afford
This codec can correct up to 3 errors and 6 erasures simultaneously
>>> print(maxerrors, maxerasures)
3 6
>>> maxerrors, maxerasures = rsc.maxerrata(errors=5, verbose=True)  # we know the number of errors, will calculate how many erasures we can afford
This codec can correct up to 5 errors and 2 erasures simultaneously
>>> print(maxerrors, maxerasures)
5 2

Note that if a chunk has more errors and erasures than the Singleton Bound as calculated by the maxerrata() method, the codec will try to raise a ReedSolomonError exception, but may very well not detect any error either (this is a theoretical limitation of error correction codes). In other words, error correction codes are unreliable to detect if a chunk of a message is corrupted beyond the Singleton Bound. If you want more reliability in errata detection, use a checksum or hash such as SHA or MD5 on your message, these are much more reliable and have no bounds on the number of errata (the only potential issue is with collision but the probability is very very low).

Note: to catch a ReedSolomonError exception, do not forget to import it first with: from reedsolo import ReedSolomonError

To check if a message is tampered given its error correction symbols, without decoding, use the check() method:

# Checking >> rsc.check(b’hello worXXXXyxb2XXx01qxb9xe3xe2=’) # Tampered message will return False [False] >> rmes, rmesecc, errata_pos = rsc.decode(b’hello worXXXXyxb2XXx01qxb9xe3xe2=’) >> rsc.check(rmesecc) # Corrected or untampered message will return True [True] >> print(‘Number of detected errors and erasures: %i, their positions: %s’ % (len(errata_pos), list(errata_pos))) Number of detected errors and erasures: 6, their positions: [16, 15, 12, 11, 10, 9]

By default, most Reed-Solomon codecs are limited to characters that can be encoded in 256 bits and with a length of maximum 256 characters. But this codec is universal, you can reduce or increase the length and maximum character value by increasing the Galois Field:

# To use longer chunks or bigger values than 255 (may be very slow) >> rsc = RSCodec(12, nsize=4095) # always use a power of 2 minus 1 >> rsc = RSCodec(12, c_exp=12) # alternative way to set nsize=4095 >> mes = ‘a’ * (4095-12) >> mesecc = rsc.encode(mes) >> mesecc[2] = 1 >> mesecc[-1] = 1 >> rmes, rmesecc, errata_pos = rsc.decode(mesecc) >> rsc.check(mesecc) [False] >> rsc.check(rmesecc) [True]

Note that the RSCodec class supports transparent chunking, so you don’t need to increase the Galois Field to support longer messages, but characters will still be limited to 256 bits (or whatever field you set with c_exp).

If you need to use a variable number of error correction symbols (i.e., akin to variable bitrate in videos encoding), this is possible always possible using RSCodec.decode(nsym=x) and at encoding by setting RSCodec(nsym=y, single_gen=False) and then RSCodec.encode(nsym=x).

Low-level usage via direct access to math functions

If you want full control, you can skip the API and directly use the library as-is. Here’s how:

First you need to init the precomputed tables:

>> import reedsolo as rs >> rs.init_tables(0x11d)

Pro tip: if you get the error: ValueError: byte must be in range(0, 256), please check that your prime polynomial is correct for your field. Pro tip2: by default, you can only encode messages of max length and max symbol value = 256. If you want to encode bigger messages, please use the following (where c_exp is the exponent of your Galois Field, eg, 12 = max length 2^12 = 4096):

>> prim = rs.find_prime_polys(c_exp=12, fast_primes=True, single=True)[0] >> rs.init_tables(c_exp=12, prim=prim)

Let’s define our RS message and ecc size:

>> n = 255 # length of total message+ecc >> nsym = 12 # length of ecc >> mes = “a” * (n-nsym) # generate a sample message

To optimize, you can precompute the generator polynomial:

>> gen = rs.rs_generator_poly_all(n)

Note: this generates the generator polynomial for all possible nsym, so this can easily be used for variable encoding rate.

Then to encode:

>> mesecc = rs.rs_encode_msg(mes, nsym, gen=gen[nsym])

Let’s tamper our message:

>> mesecc[1] = 0

To decode:

>> rmes, recc, errata_pos = rs.rs_correct_msg(mesecc, nsym, erase_pos=erase_pos)

Note that both the message and the ecc are corrected (if possible of course). Pro tip: if you know a few erasures positions, you can specify them in a list erase_pos to double the repair power. But you can also just specify an empty list.

You can check how many errors and/or erasures were corrected, which can be useful to design adaptive bitrate algorithms:

>> print(‘A total of %i errata were corrected over all chunks of this message.’ % len(errata_pos))

If the decoding fails, it will normally automatically check and raise a ReedSolomonError exception that you can handle. However if you want to manually check if the repaired message is correct, you can do so:

>> rs.rs_check(rmes + recc, nsym)

Note: if you want to use multiple reedsolomon with different parameters, you need to backup the globals and restore them before calling reedsolo functions:

>> rs.init_tables() >> global gf_log, gf_exp, field_charac >> bak_gf_log, bak_gf_exp, bak_field_charac = gf_log, gf_exp, field_charac

Then at anytime, you can do:

>> global gf_log, gf_exp, field_charac >> gf_log, gf_exp, field_charac = bak_gf_log, bak_gf_exp, bak_field_charac >> mesecc = rs.rs_encode_msg(mes, nsym) >> rmes, recc, errata_pos = rs.rs_correct_msg(mesecc, nsym)

The globals backup is not necessary if you use RSCodec, it will be automatically managed.

The speed-optimized C extension creedsolo can be used similarly once compiled or cythonized:

>> import creedsolo as crs >> codec = crs.RSCodec(10)

If you want to cimport the module, you will need to directly access the full package path:

>> import cython >> cimport cython >> cimport creedsolo.creedsolo as crs

Low-level functions allow to construct new APIs on top of this codec, such as an automatic Reed-Solomon decoder that can search for viable parameters to decode from an unknown Reed-Solomon codec.

If you want to learn more about which internal functions to use and for what purposes, read the sourcecode’s comments (we follow literate programming principles) for more info about how it works and the various parameters you can setup if you need to interface with other RS codecs.

Extended description

The code of wikiversity is here consolidated into a nice API with exceptions handling. The algorithm can correct up to 2*e+v <= nsym, where e is the number of errors, v the number of erasures and nsym = n-k = the number of ECC (error correction code) symbols. This means that you can either correct exactly floor(nsym/2) errors, or nsym erasures (errors where you know the position), and a combination of both errors and erasures. This is called the Singleton Bound, and is the maximum/optimal theoretical number of erasures and errors any error correction algorithm can correct (although there are experimental approaches to go a bit further, named list decoding, not implemented here, but feel free to do pull request!).

The code should work on pretty much any reasonable version of python (3.7+), but I’m only testing on the latest Python version available on Anaconda at the moment (currently 3.10), although there is a unit test on various Python versions to ensure retrocompatibility.

This library is also thoroughly unit tested with branch coverage, so that nearly any encoding/decoding case should be covered. The unit test includes Cython and PyPy too. On top of the unit testing covering mathematical correctedness in this repo here, the code is in practice even more thoroughly covered than shown, via the pyFileFixity <https://github.com/lrq3000/pyFileFixity/>`_ unit test, which is another project using reedsolo for the practical application of on-storage data protection, and which includes a more pragmatic oriented unit test that creates and tamper files to ensure that reedsolo does work in practice to protect and restore data.

The codec is universal, meaning that it should be able to decode any message encoded by any other RS encoder as long as you provide the correct parameters. Beware that often, other RS encoders use internal constant sometimes hardcoded inside the algorithms, such as fcr, which are then hard to find, but if you do, you can supply them to reedsolo.

The work on this module is motivated by the aim to offer a solution for long-term archival of data, although this can and is also used for communication streams. For this purpose, this module is an ideal choice: Reed-Solomon is an optimal (non-quantic) algorithm, it corrects up to the Singleton Bound which is the absolute limit of how much erratas an error-correction algorithm can correct, RS is hence future-proof. The universality of this implementation further ensures that other future implementations of Reed-Solomon should be able to decode data encoded with this universal codec.

Note that if you use higher fields (ie, bigger c_exp), the algorithms will be slower, first because we cannot then use the optimized bytearray() structure but only array.array('i', ...), and also because Reed-Solomon’s complexity is quadratic (both in encoding and decoding), so this means that the longer your messages, the quadratically longer it will take to encode/decode!

The algorithm itself can handle messages of a length up to (2^c_exp)-1 symbols per message (or chunk), including the ECC symbols, and each symbol can have a value of up to (2^c_exp)-1 (indeed, both the message length and the maximum value for one character is constrained by the same mathematical reason). By default, we use the field GF(2^8), which means that you are limited to values between 0 and 255 (perfect to represent a single hexadecimal symbol on computers, so you can encode any binary stream) and limited to messages+ecc of maximum length 255. However, you can “chunk” longer messages to fit them into the message length limit. The RSCodec class will automatically apply chunking, by splitting longer messages into chunks and encode/decode them separately; it shouldn’t make a difference from an API perspective (ie, from your POV).

Speed optimizations

Thanks to using bytearray and a functional approach (contrary to unireedsolomon, a sibling implementation), the codec has quite reasonable performances despite avoiding hardcoding constants and specific instruction sets optimizations that are not mathematically generalizable (and so we avoid them, as we want to try to remain as close to the mathematical formulations as possible).

In particular, good speed performance at encoding can be obtained by using either PyPy JIT Compiler on the pure-python implementation (reedsolo.py) or either by compiling the Cython extension creedsolo.pyx (which is much more optimized and hence much faster than PyPy).

From our speed tests, encoding rates of several MB/s can be expected with PyPy JIT, and 14.3 MB/s using the Cython extension creedsolo on an Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz (benchmarked with pyFileFixity’s ecc_speedtest.py).

Decoding remains much slower, and less optimized, but more complicated to do so. However, the rationale to focus optimization efforts primarily on encoding and not decoding is that users are more likely to spend most of their processing time encoding data, and much less decoding, as encoding needs to be done indiscriminately apriori to protect data, whereas decoding happens only aposteriori on data that the user knows is tampered, so this is a much reduced subset of all the protected data (hopefully).

To use the Cython implementation, it is necessary to pip install cython==3.0.0b2 and to install a C++ compiler (Microsoft Visual C++ 14.x for Windows and Python 3.10+), read the up-to-date instructions in the official wiki. Then simply cd to the root of the folder where creedsolo.pyx is, and type python setup.py build_ext --inplace --cythonize. Alternatively, it is possible to generate just the C++ code by typing cython -3 creedsolo.pyx. When building a distributable egg or installing the module from source, the Cython module can be transpiled and compiled if both Cython and a C compiler are installed and the --cythonize flag is supplied to the setup.py, otherwise by default only the pure-python implementation and the .pyx cython source code will be included, but the binary won’t be in the wheel.

Then, use from creedsolo import RSCodec 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, which includes a fake _bytearray function that overloads the standard bytearray with an array.array("i", ...) 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

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.

Migration from v1.x to v2.x

If you used reedsolo v1.x, then to upgrade to v2.x, a few changes in the build requirements, the build system and API must be considered.

One major change is that Cython>=v3.0.0b2 is required to cythonize creedsolo.pyx. To ease migration for operating systems where python packages pre-releases are not available, the intermediary creedsolo.c is also shipped in the standard distribution (the tar.gz file) to allow compilation with any C compiler, without requiring Cython.

Furthermore, the packaging system was overhauled to be PEP 517 standard compliant, so that it now supports build isolation by default, and it uses a src-layout.

While we tried to keep the import API the same (you can still do import reedsolo as rs; codec = rs.RSCodec(10) and similarly import creedsolo as crs. However, if you used to cimport creedsolo as crs using the fast c-import system provided by Cython, now you will need to cimport creedsolo.creedsolo as crs.

Indeed, for Linux distributions package maintainers, it’s important to note the module is now using a “src-layout”, instead of the “single-module-layout” before, so this may require some adjustments in packages building processes.

Furthermore, wheels with a precompiled creedsolo.pyd extension are now built for multiple platforms and Python releases and uploaded to PyPi, thanks to cibuildwheel, and the process is automated with a GitHub Action. In future releases, we will try to improve on build reproducibility, such as by implementing a lockfile (but not there yet, there is no standard for that) and moving away from setuptools (potentially to meson).

Support for Python 2.7 and Python <= 3.6 was dropped as advised elsewhere, as only the pure python implementation remained retrocompatible, but not the cython extension, so that it is better for older Py2.7 users to simply stick to the fully functional reedsolo v1.7.0. For Python 3.6, support was dropped because these environments are not supported officially anymore by GitHub Actions, so it is harder to unit test and hence no guarantee of correctedness can be provided anymore in an automated fashion, so it’s better to also use reedsolo v1.7.0 for these older Py3 versions.

About API changes, a few bugfixes were implemented in the pure python implementation, but breaking changes were limited as much as possible (if there is any, it is unintended). For the creedsolo extension, there are LOTS of changes, hence why the major version change (we try to follow SemVer). We will not list everything here, but the biggest breaking change is that now internally, everything is either a bytearray, or a CPython array('i', ...). So this means that when interacting with creedsolo, you want to always supply a bytearray object, you can’t just provide a list or a string anymore. For reedsolo, this is still supported, since it transparently converts to a bytearray internally, for ease of use.

For the pure python implementation reedsolo, this should not change much, it should be retrocompatible with lists (there are a few checks in place to autodetect and convert lists into bytearrays whenever necessary - but only in RSCodec, not in lower level functions if that’s what you used!).

However, for the cythonized extension creedsolo, these changes are breaking compatibility with v1.x: if you used bytearray everywhere whenever supplying a list of values into creedsolo (both for the data and erasures_pos), then all is well, you are good to go! On the other hand, if you used list objects or other types in some places, you are in for some errors.

The good news is that, thanks to these changes, both implementations are much faster, but especially creedsolo, which now encodes at a rate of 15-20 MB/s (yes that’s BYTES, not bits!). This however requires Cython >= 3.0.0b2, and is incompatible with Python 2 (the pure python reedsolo is still compatible, but not the cythonized extension creedsolo).

In practice, there is likely very little you need to change, just add a few bytearray() calls here and there. For a practical example of what was required to migrate, see the commits for pyFileFixity migration.

Projects using reedsolo

Reedsolo is a critical component of numerous solutions, such as:

  • Matter (ex-Project CHIP) - The new standard for the Internet of Things (IoT): Matter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.

  • esp-idf - Espressif IoT Development Framework. Official development framework for Espressif SoCs, such as ESP32, which are very widespread reprogrammable electronic cheaps for scientific, prototype and DIY projects, especially with Arduino and MicroPython.

  • esptool - A Python-based, open-source, platform-independent utility to communicate with the ROM bootloader in Espressif chips.

  • pyFileFixity - A suite of tools for long term archival of files.

  • amodem - Audio MODEM Communication Library in Python, allowing true air-gapped communication (via a speaker and a microphone), or an audio cable (for higher transmission speed).

  • SteganoGAN - SteganoGAN is a tool for creating steganographic images using adversarial training.

  • galacteek - Multi-platform browser for the distributed web.

  • ofrak - OFRAK (Open Firmware Reverse Analysis Konsole) is a binary analysis and modification platform.

  • HoloCubic AIO - All-in-One open-source firmware for the HoloCubic device with a wide features set.

  • MicroPython-Stubber - Boost MicroPython productivity in VSCode: Generate and use stubs for different micropython firmwares to use with vscode and pylance or pylint.

  • qr-backup - Paper backup of files using QR codes.

  • Jade - Jade Hardware Wallet.

  • pied-piper - Defunct popular module for data transfer over sound waves.

  • qreader - A defunct pure python QR code reader.

  • sonicky - Proof-of-concept Python and Android modules for connectionless ultrasonic message transfer.

  • neighborhood-connectivity - An example app that implements a noisy communication between clique of thread group with very high error correction handling ability and O(1) rounds of messages sending.

  • audiotagger - Clever use of error correction codes to wirelessly synchronize multiple concurrent video feeds of amateur video filmmakers by injecting AFSK packets with timestamp and location metadata in the audio channel communicated via radios.

  • Several research papers used reedsolo, see a list here.

And many, many more!

Similar projects

Here is a non-exhaustive list of similar projects (ie, projects implementing a Reed-Solomon codec): * galois, a Numba JIT-optimized extension module for Numpy, which implements a Reed-Solomon codec and NTT transforms. * generalizedReedSolomon, a variant of an implementation of Reed-Solomon that is more parallelizable and interestingly can encode messages of arbitrary length without chunking (the chunking is kind of integrated in the parallelization). Internally uses numpy’s fft and ifft. Maybe translatable to use Number Theoretic Transform (NTT) instead of FFT.

Authors

This module was conceived and developed by Tomer Filiba in 2012.

It was further extended and is currently maintained by Stephen Karl Larroque since 2015.

And several other contributors helped improve and make it more robust, thanks a lot to them!

Contributors

For a list of all contributors, please see the GitHub Contributors graph and the commits history.

License

This software is released under your choice of the Unlicense or the MIT-0 (MIT No Attribution) License. Both licenses are public-domain-equivalent licenses, as intended by the original author Tomer Filiba.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

reedsolo-2.1.1b1.tar.gz (380.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

reedsolo-2.1.1b1-pp39-pypy39_pp73-win_amd64.whl (504.9 kB view details)

Uploaded PyPyWindows x86-64

reedsolo-2.1.1b1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (550.6 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (535.0 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl (505.2 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

reedsolo-2.1.1b1-pp38-pypy38_pp73-win_amd64.whl (504.2 kB view details)

Uploaded PyPyWindows x86-64

reedsolo-2.1.1b1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (561.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (545.3 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl (504.3 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

reedsolo-2.1.1b1-pp37-pypy37_pp73-win_amd64.whl (504.0 kB view details)

Uploaded PyPyWindows x86-64

reedsolo-2.1.1b1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (561.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (545.3 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (504.3 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

reedsolo-2.1.1b1-cp311-cp311-win_amd64.whl (517.5 kB view details)

Uploaded CPython 3.11Windows x86-64

reedsolo-2.1.1b1-cp311-cp311-win32.whl (487.3 kB view details)

Uploaded CPython 3.11Windows x86

reedsolo-2.1.1b1-cp311-cp311-musllinux_1_1_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ x86-64

reedsolo-2.1.1b1-cp311-cp311-musllinux_1_1_i686.whl (1.4 MB view details)

Uploaded CPython 3.11musllinux: musl 1.1+ i686

reedsolo-2.1.1b1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-cp311-cp311-macosx_10_9_x86_64.whl (541.3 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

reedsolo-2.1.1b1-cp310-cp310-win_amd64.whl (516.8 kB view details)

Uploaded CPython 3.10Windows x86-64

reedsolo-2.1.1b1-cp310-cp310-win32.whl (487.2 kB view details)

Uploaded CPython 3.10Windows x86

reedsolo-2.1.1b1-cp310-cp310-musllinux_1_1_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

reedsolo-2.1.1b1-cp310-cp310-musllinux_1_1_i686.whl (1.3 MB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ i686

reedsolo-2.1.1b1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (1.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-cp310-cp310-macosx_10_9_x86_64.whl (540.8 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

reedsolo-2.1.1b1-cp39-cp39-win_amd64.whl (516.9 kB view details)

Uploaded CPython 3.9Windows x86-64

reedsolo-2.1.1b1-cp39-cp39-win32.whl (487.6 kB view details)

Uploaded CPython 3.9Windows x86

reedsolo-2.1.1b1-cp39-cp39-musllinux_1_1_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ x86-64

reedsolo-2.1.1b1-cp39-cp39-musllinux_1_1_i686.whl (1.3 MB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ i686

reedsolo-2.1.1b1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (1.3 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-cp39-cp39-macosx_10_9_x86_64.whl (541.2 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

reedsolo-2.1.1b1-cp38-cp38-win_amd64.whl (517.0 kB view details)

Uploaded CPython 3.8Windows x86-64

reedsolo-2.1.1b1-cp38-cp38-win32.whl (487.6 kB view details)

Uploaded CPython 3.8Windows x86

reedsolo-2.1.1b1-cp38-cp38-musllinux_1_1_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ x86-64

reedsolo-2.1.1b1-cp38-cp38-musllinux_1_1_i686.whl (1.4 MB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ i686

reedsolo-2.1.1b1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (1.3 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-cp38-cp38-macosx_10_9_x86_64.whl (545.2 kB view details)

Uploaded CPython 3.8macOS 10.9+ x86-64

reedsolo-2.1.1b1-cp37-cp37m-win_amd64.whl (513.7 kB view details)

Uploaded CPython 3.7mWindows x86-64

reedsolo-2.1.1b1-cp37-cp37m-win32.whl (484.2 kB view details)

Uploaded CPython 3.7mWindows x86

reedsolo-2.1.1b1-cp37-cp37m-musllinux_1_1_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ x86-64

reedsolo-2.1.1b1-cp37-cp37m-musllinux_1_1_i686.whl (1.3 MB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ i686

reedsolo-2.1.1b1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ x86-64

reedsolo-2.1.1b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (1.3 MB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

reedsolo-2.1.1b1-cp37-cp37m-macosx_10_9_x86_64.whl (537.2 kB view details)

Uploaded CPython 3.7mmacOS 10.9+ x86-64

File details

Details for the file reedsolo-2.1.1b1.tar.gz.

File metadata

  • Download URL: reedsolo-2.1.1b1.tar.gz
  • Upload date:
  • Size: 380.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1.tar.gz
Algorithm Hash digest
SHA256 5659d59208af96fe5abf07e72b49c17a1788d4d2962292268a3080ddb39085c4
MD5 1c1d851ca36da7838bf503dd7c1a1132
BLAKE2b-256 7d72d679db66834182f19d6d5cbd41c8a326bf73f83c7757dd3de7a595175183

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp39-pypy39_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp39-pypy39_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 b8290ea4807860f2d514a943e54673b93136d1a884cf6a36b4d1d84d5e3abe40
MD5 4485f986c42611ae5764b64913d0a5ba
BLAKE2b-256 73b2110f46c62eb368c176d689c6016fb5d4367ac759b54b10d27bf800c13f5f

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a0a0a6479ab29457ed6b4c67d45f97738296238dcc16fe91e0b7db8e91446709
MD5 e683b8d7b80362e6ba1bc9c6ad16b47c
BLAKE2b-256 bc242ec2ba756aa7c1247ee79bc45e1e772e4d280e9a4b047d08dd87f6dd70b7

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 532149a55c34b7170b35ed70bcaea180a03abc17b51cf1ae28986669a855fd8c
MD5 da06cef21502de934594874cff7bc748
BLAKE2b-256 c43aeb1c2a77c799e71a2591a154d85a80fd0a2013015d6eed3da3696161d0cc

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d6b6889e6030291aa76114290438f6e90b534225b08f03b3bfcc5be1f2c6c888
MD5 a7fc7805118d69d15862805769cf63f4
BLAKE2b-256 37aa50dc91eecfeab516cfbfb86abd6a2784875182f939864b8a06010b32a308

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp38-pypy38_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp38-pypy38_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 b410c7fc738c082f5c1a51df6d496b0ada12d9e57d22be209f511a35f96adcd5
MD5 5d19a696f3560201802ec06f65caf186
BLAKE2b-256 e3b65bd5259cca7676d4caaefb4c38d6aa89da78211f96305c4f934d57903ac7

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 98d6ed4c370ee3bd9bfaa8e1f4f633a3678c165adfdf811a1e0a3f8d643c37b3
MD5 4415ba65b0db1e1bf4235e77bf2afb81
BLAKE2b-256 3d4632c6523479c49dd8b91251c10dfd2c97947e168fff6167684d3038ff53e7

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 e106bb0975dfb2b61ff7956ed643e61ab7a182aea50b61a1710bc238569c85c4
MD5 eb0a955d5c8188d371805bba04d32802
BLAKE2b-256 0e60c81cc4a289cf470147d17d0253332dc2af5dd00c3aa677457a63a32b9ce8

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d211f0103a8a913501c70cece7812ef5754453afa4f8dd10b75c1c8a7412d013
MD5 c0ddd0daa752d9e1ed77000ccaab28e6
BLAKE2b-256 0ac455d8fed36afbb19083944b87bd78cd7018da97186e6502431095cea0fda7

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp37-pypy37_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 78eb6de947ba9e7d26791ef00baf699ba581d533510f430993a8b6a8765445d9
MD5 0bb6747cf8dacb9151ba5e8991beafcb
BLAKE2b-256 fbcaac3446dc5c1f8479017f04761490509ea62cd30b0c30e63004033fb77b7e

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e88c50209c213e5690d0bcdd587230ec595e3a27d6e7e65956f5fbd29e323446
MD5 1f2b7c1c3fe0545299e4a938e6dcdcf8
BLAKE2b-256 2c20233a4d37c52cdaa95f2ca447f4e97533ab90d5402c1f272f2480d50777b7

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 ba08bbfc3334374d4792c17f446ce63bf4b0198b8a63971a99d7fe798f077f74
MD5 de463a9638233324c4282f3cc40f12fb
BLAKE2b-256 bab7b128f6e9e391426477d087f70e5945ce93e46d11d6034addb6ceaa2a1c80

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 daaadb6d5869fee0609fe2e9c25dbfac1c1dd70bc3a8718b932261471a927548
MD5 e59067b7a3da5a6a74c8ae0e727cca6e
BLAKE2b-256 4e86986ec5f2d7a7022c9a1a4a1d9632fcb4ecf60e7ca11a20d6cb34b556673d

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 517.5 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 95221e0ef7319f1fa9beac104e358b2c418e502fd541aeff1512e130ad872306
MD5 7eed55841ea8a7a20a743cc42199b84d
BLAKE2b-256 f9587a5ffee7c5732b2e967148e5251c52f8bd33f27cbf844aad855dc225bf88

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-win32.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp311-cp311-win32.whl
  • Upload date:
  • Size: 487.3 kB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 83d3402573a9edf5f0a6dd6f3867789b24542a37725c830345d7ddd5355fa4f9
MD5 7f005edf96a677e19d01c1ec530f7707
BLAKE2b-256 612957b75f089fb642902f4c280e09fed95c9687a24ed5697a5b2fea887e1411

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 4f95df10ef6a7e07911cda0cab9d1f176614becd21f9e5ef16c7bf249914f50f
MD5 d2dfd764b46d1cf3d2601a46570e85e7
BLAKE2b-256 5e9e512eacde4040acb8d2f10bf9458f03b6ed1ddcecc0a84626655a9af437b9

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 71c353c1fdfa3bbb0b79de3d66a6cf8180d71eaab58fdc3c9e919a9ff9f827b4
MD5 94815fec3d251be712aa5901869e4b04
BLAKE2b-256 2237c532e199850d0904c3c448ec1149d2edaab437c748371410bd2b22a1e942

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 63948631e60813955c545cd4f6f2f97167b8277c3ab8573f62636c11c072bec0
MD5 663a89337262508727dc0c83aa1359cb
BLAKE2b-256 bfb720ce0f2ab0a34e4e58afce98939d1d4b222d5241a19a4789e4836da7ac6f

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9ab9065da099ac63b00d7baa3832bd37b99bac416376830afefa45f527db5e0a
MD5 98aaff23a91b3e135cab084a571f7147
BLAKE2b-256 4204271a4bc532b6527e9b3312eb190552884b3ee5eaf62bb350888752376150

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 b00a9783a00b950f6f793d250ea933c6971680417493bee5e75c91732f9aac62
MD5 db4a8899dde56e682d2a36c9c53643ab
BLAKE2b-256 e8c21e03f88df406806a7601b23b484e0707badf80b6112b58af4abf88064075

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 516.8 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 74e09fcb3a15f70d7134a069f3b3121ff44d94cdf6699ec9569a2051e1e99557
MD5 40362104d99633558d63c4ce75c2bdec
BLAKE2b-256 855335cde0bdc358fcb13ceaae1982818e1ef5d0d691e38640cd6a45c357b7a1

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-win32.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp310-cp310-win32.whl
  • Upload date:
  • Size: 487.2 kB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 5385f3feca69361706fd3588db2b26026571a8149c0e791aeea022854027846e
MD5 1d1f5e6bdf424eecf0b7defec6f5d633
BLAKE2b-256 dbed618130d726e74436616b88153f4051d0c6cada3bc81fd1e5542ac4fbdb6f

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d85b36f303e173046bd9b2ca7f9a9fc12d6e3a353a3e3c5340840b8105c70234
MD5 320c78d43d76bda272fc74d4fefb5c5f
BLAKE2b-256 9815ec651cc4b09afc2f8b30463e5dc12fc4a8937471e672008933a431a3a622

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 cb34a6d5e71a2ea8a0d9e381aff7536c5f82952504fda296cbae7710a268038a
MD5 395a7f74f64904ce94891b9660edfbc5
BLAKE2b-256 b0a52de0390db9b12e738d5d30b7df375c678d22613a7b54835fdfb9fe3aa27f

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a6176e7e63cbe492bf7770f8448075900432b3a1f107042d72bdc94442a90312
MD5 d09e38f3251c723c5109c983b1ad5974
BLAKE2b-256 c023205dae5fe88e4e5017a2348e4d065206155ed2861b25d49d03311653d35d

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 5a480fd69512a518d71b779d951be44f359c327adc66320b5bce182c1af90870
MD5 ca6c94b2d929289267f1cfe35da692e2
BLAKE2b-256 dcca2ca43438eeb33161ecb82744e3f644a2ae7118f410b5b576bd6358e7c8d0

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 9231a10aa2090e74650d44c39f8d1b0e29f3dfe2f15263d01a5d5116a0a79721
MD5 2d053240e7a2323dfd966a2c62ea72d3
BLAKE2b-256 26f8ee22bb06c2689a0958f6d4fad99fd2fe40009f4f12b92a42ae2b19f93205

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 516.9 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 d6194f5d465c6c665755f808cf24eaef8a95bd3217727c7448ba6f3ce47d0683
MD5 e82fe4765ca5503bd28c79940f6e31f9
BLAKE2b-256 f443e67810ad6b2d36d52bab9c87a7695f3e3a1bcee435191998298eb82f52a8

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-win32.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp39-cp39-win32.whl
  • Upload date:
  • Size: 487.6 kB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 e8575ac8cad57a7b1679dd37c48b81b7588d72602ce6db51f95ae0141022eed2
MD5 7452036f43d89a9592d623333708ad37
BLAKE2b-256 d887c5d576ed0dc4938f41e9ec5959432829220670195732b5dde67f4aa30996

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 f6a151be6845dccd8d0978eab6e0869f1a37ca8e33c71bc2a7e9da21b8320fd9
MD5 7ee182d6bfaa97baeb8c8e924af7fcac
BLAKE2b-256 3a25e372f072817034bb81194402778e474483cbf2e7abcf3036101ed04561cb

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 f61bc0a3d9ca3abd1f6ce65c08ee4c7823b17f1a0272f902c391212afb66664d
MD5 7b4d0ddecfa0313c9c38cdab56db09f3
BLAKE2b-256 776c5263a912a874f5f9d75d67e98616aa2bae8c4dbc13cb26f1317643d420a0

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 66de0aa486d90d548f9fe239f18fa26cacce4eb78b35d7891788d2a399c284ad
MD5 587b40644884d852eebd8f2d83df1ad1
BLAKE2b-256 3ae12abf5423c37e2b89f2920acb63ede8fe12ee45758182670949f13ecb0501

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3cf2fa73050c14343ad1f999fd05d0ac6fe9e0520f82fe20e358ac6c3a3b98bb
MD5 d87b804be085255620f6fa4f795b5f0a
BLAKE2b-256 1a2d9e06f82d208e46e004a09b0f9ebe363444687500b3c1c57820c95d0e650c

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 6492f85065928e2705deda918c8067ced64360bd6f4fa7bb77ef968ce67fd114
MD5 c63d4b6df73a797778ce80d2bb9f7c74
BLAKE2b-256 6eb20ca63967cd59f405b37ed377f19fd7cfe493ef412dcb0b393da7c407a7ec

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 517.0 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 2d46fa5c37ad05d2e80e2e9a45dc5cd2c3f979d156e055439921b0b5ba16212e
MD5 1b3864d2430328ef6e1e5efb30934abe
BLAKE2b-256 02b61af43c64f6d5fafeca353a10f40fc3323ebceb4b44274508fb96474a1b4a

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-win32.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp38-cp38-win32.whl
  • Upload date:
  • Size: 487.6 kB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 dfc5024a14ae75a19d412e72e471fd5753ea67e7d60572e10814f4139d344f36
MD5 b9d67d9d752781a78c6bc785da827c6c
BLAKE2b-256 affa4af83eaa015d0b14d716469a7b6814a0f1c448606486b00e8ca0bbe55f2d

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 95841685b687fb69b614144f2e66679472ba6b828e1534393324077608e1c8ed
MD5 c8e090289c99193e1d02112dc73e33bb
BLAKE2b-256 2d7324c2e9e1eb06065809e22cb28460c3786524224b0c55021d4ca32d93a117

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 e03f6f8e2628623ae54a02b850b468cf914fa38cf75226b8725a4b3365509d86
MD5 fa944e754c365461189096832d0ab070
BLAKE2b-256 d86e71383c267bbe6a87fb793cbd382920141453be71f74e19e769fe7279986f

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6f997bb40345b27a433b3929bb0529658db65c20e388855a1a8a5c0fc9455ad5
MD5 fd31b9810a6bf4ed5f087e92dde1d872
BLAKE2b-256 ee5fe0185a9e7baa14836271027075265194ffe90e03e6dbcb1821686566f615

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 bbc2d370e78d9ac88520a36acc313fb39872dfbff25b045dd714919adb71641c
MD5 c871b6787019f46bbfe85b29fbfce234
BLAKE2b-256 adaa2345cd5123aeeb7b830b032b3bf3562c3924182ef3dc989e3e15d4539b13

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d0982181ca76685cad8513a49c3ab0fabea36b89f135dd5d22534d6da8f1ac8b
MD5 7f9460cab0126825886396398e0cdf79
BLAKE2b-256 574636cc2cf51e338fdbdae200d345697157726c51ee278197bb770b0acfb6cc

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 513.7 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 86e95178787adcf1d99a7e5db68b77e7d9db787a10d414baf4d9311f729ae7d1
MD5 22d2baf0936f06befc8bf7af08d4e5bd
BLAKE2b-256 51750ee1291b50dedad15a119684d16fa63513548e8e1b17e605d0f042b0709c

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-win32.whl.

File metadata

  • Download URL: reedsolo-2.1.1b1-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 484.2 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 3d5df10ac020f942832109adc35fc65e60d728fde9223f5d88ff48f1cec4c48a
MD5 0d16e2c356a8bc80290d63d6e4759120
BLAKE2b-256 4eb5ab903d29cf547bf9bb45ab9d0e72331bd58e151ba5f6bf1e9cb03f4f8ce2

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 fb91e07530ceb066566cf9e59847ca815e40e4a2c132c14b6f8bbf47ba63bf07
MD5 21e9de31548b56958551c2b3d80e1f7a
BLAKE2b-256 56d027de43f3c442502a94a52b84fb04defed05efcdfa3fc3dbda4156a54d58b

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 9d4bbe02f942fa97eadde6493956b542e0e5f9550183d75ec492adfb73d07887
MD5 fce0cf9c65d9d05f0820c881f0b65ea5
BLAKE2b-256 9bdf8a70ddee14e222a01924cd7adb67ad7928782ffe9b1fd19015bc113d4a7b

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ce8a3af14c8e5f5c6498db5357d54a959b1f9973c56d92da3f50ec3f12e862bd
MD5 eb4c171f4f705df48bd8f286e81a78fe
BLAKE2b-256 4bf2cae9fd17e9b1a7e58db35fdec9e10e761137896493e84617ad26c09ad4d8

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d27dac3ac20cb16ac7e9dd2b00e271a05149b2a0fe37e3bc7f54286ac11ae140
MD5 5bbddf5f5501201e3529523e60439797
BLAKE2b-256 cbae8b6d115efb4173d9882345a343ed2fa98d912ad43825fd068a91b15cbb33

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.1b1-cp37-cp37m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for reedsolo-2.1.1b1-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 35eb3f543e124ecc147e4ebdb33a6c773136167150ecbb751d348d29648602ca
MD5 2efe46c78f300dff3039278dcfe2099b
BLAKE2b-256 e8f7e9e0c88de8e9d4d6e329fb446621323f9e112c458bedf94f9afe90c472dc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page