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:

pip install reedsolo --no-binary={reedsolo}

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 --config-setting="--build-option=--cythonize" --verbose
# To compile from the latest development release:
pip install --upgrade reedsolo --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" --config-setting="--build-option=--cythonize" --use-pep517 --isolated --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.

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.

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 any viable set of codec parameters if they are apriori unknown.

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!

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.0.31b1.tar.gz (379.0 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.0.31b1-pp39-pypy39_pp73-win_amd64.whl (502.4 kB view details)

Uploaded PyPyWindows x86-64

reedsolo-2.0.31b1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (545.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.0.31b1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl (501.4 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

reedsolo-2.0.31b1-pp38-pypy38_pp73-win_amd64.whl (502.5 kB view details)

Uploaded PyPyWindows x86-64

reedsolo-2.0.31b1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (556.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.0.31b1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl (501.2 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

reedsolo-2.0.31b1-pp37-pypy37_pp73-win_amd64.whl (502.5 kB view details)

Uploaded PyPyWindows x86-64

reedsolo-2.0.31b1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (556.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.0.31b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (501.3 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

reedsolo-2.0.31b1-cp311-cp311-win_amd64.whl (515.5 kB view details)

Uploaded CPython 3.11Windows x86-64

reedsolo-2.0.31b1-cp311-cp311-win32.whl (485.5 kB view details)

Uploaded CPython 3.11Windows x86

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

Uploaded CPython 3.11musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.11musllinux: musl 1.1+ i686

reedsolo-2.0.31b1-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.0.31b1-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.0.31b1-cp311-cp311-macosx_10_9_x86_64.whl (538.4 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

reedsolo-2.0.31b1-cp310-cp310-win_amd64.whl (514.7 kB view details)

Uploaded CPython 3.10Windows x86-64

reedsolo-2.0.31b1-cp310-cp310-win32.whl (485.5 kB view details)

Uploaded CPython 3.10Windows x86

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

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.10musllinux: musl 1.1+ i686

reedsolo-2.0.31b1-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.0.31b1-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.0.31b1-cp310-cp310-macosx_10_9_x86_64.whl (537.8 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

reedsolo-2.0.31b1-cp39-cp39-win_amd64.whl (514.8 kB view details)

Uploaded CPython 3.9Windows x86-64

reedsolo-2.0.31b1-cp39-cp39-win32.whl (485.7 kB view details)

Uploaded CPython 3.9Windows x86

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

Uploaded CPython 3.9musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.9musllinux: musl 1.1+ i686

reedsolo-2.0.31b1-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.0.31b1-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.0.31b1-cp39-cp39-macosx_10_9_x86_64.whl (538.3 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

reedsolo-2.0.31b1-cp38-cp38-win_amd64.whl (515.0 kB view details)

Uploaded CPython 3.8Windows x86-64

reedsolo-2.0.31b1-cp38-cp38-win32.whl (485.8 kB view details)

Uploaded CPython 3.8Windows x86

reedsolo-2.0.31b1-cp38-cp38-musllinux_1_1_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.8musllinux: musl 1.1+ i686

reedsolo-2.0.31b1-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.0.31b1-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.0.31b1-cp38-cp38-macosx_10_9_x86_64.whl (542.5 kB view details)

Uploaded CPython 3.8macOS 10.9+ x86-64

reedsolo-2.0.31b1-cp37-cp37m-win_amd64.whl (511.9 kB view details)

Uploaded CPython 3.7mWindows x86-64

reedsolo-2.0.31b1-cp37-cp37m-win32.whl (483.1 kB view details)

Uploaded CPython 3.7mWindows x86

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

Uploaded CPython 3.7mmusllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.7mmusllinux: musl 1.1+ i686

reedsolo-2.0.31b1-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.0.31b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (1.2 MB view details)

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

reedsolo-2.0.31b1-cp37-cp37m-macosx_10_9_x86_64.whl (534.2 kB view details)

Uploaded CPython 3.7mmacOS 10.9+ x86-64

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1.tar.gz
Algorithm Hash digest
SHA256 bda28c48e02ebfb002ad72cb0be29c3b97479069c91d091fd86a9710e7edd249
MD5 8e3a2c010995e1e31605a33c3b028c6d
BLAKE2b-256 b1632a66eac258b21265f68968cd3a847a174976f499e1831bf4237ddb4c9d2b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp39-pypy39_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 69c5a9f77adb463e29bf8accdc6a5588ccf7eba03caba6ef9702a2bd9fb6fdb6
MD5 3a92d9a3791ff3482e113d63dbd2316e
BLAKE2b-256 3bfe78113919fc6155142ebc17de0df81d278df730daa2bae1cb60896ad24b86

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1a57dc7b2bfefbc2450c8d5dad9f4514d664561dc78a3c7076fafaa9709ef3ca
MD5 a391e7990cbf15cda8649d02259e3370
BLAKE2b-256 0c9a344faefa9023882f10934f6c49c5304e44964073da8616e9cf8c75236f8f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 e5837b80424c82104a4b98e96afc83612686f0de42cd3a42c1f5065b30e5e2f3
MD5 c3b7c04706c17529d195c6097389e4b9
BLAKE2b-256 63d69fc1c9733f2897be153283476acd810e49f0515bcb60c849d5767ba56e9e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2c5f262babc2eb13acd44cc31320e6dc1ada3eb9ee63131b021de669b403d73c
MD5 8840bde1433a57c47df12978871a864e
BLAKE2b-256 420ab3c1a39818f769a30dc44113a606add98d88db2dcfea22fad861c25a9151

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp38-pypy38_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 6c1f27f04a62ce26275416f85e0f56b6e9281f5cfddef741f1bec147135cb7df
MD5 a4648acdb365219796db7964f08c32bf
BLAKE2b-256 c91e6771c0dcebb3e2e536c4f14c3c458da01a8242ff971a7580228f14f77f8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c648aaf1c70f2f0025eb05c6799e417c22597d4a2f329c07f9b34a11931a339d
MD5 92741164be3793852d11df7a99d6fbe4
BLAKE2b-256 d24eecf96e002aff1fe57e60748f701900361806fbc64321d2699e4594c86938

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0b3c0998db3e70916226f76d510bece5e4952ab7234fb257fb639aee377f00e4
MD5 964dff3c5bc4372c0cac5b1e67cd3bb6
BLAKE2b-256 f2b4ca9864124296476cad63ebcbc54f2759020cf2c631d879c4d5c13a006c21

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2bbc96c80052352c6c04641f12137324ecb31bf52c7af8090162fdcf45db1c82
MD5 de0b7cc68ffef98282458b83fc35759b
BLAKE2b-256 8a1bf3affc1f795ef9b5448f7941d31644ddc3440d731286415781a1c7950130

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 08a1096b677a8184a0562d09b60a3366914ca8c6a3e1818bb87490afc5cf5120
MD5 4a29928189032849fc8f7f5067e331b1
BLAKE2b-256 7becbe955dbb52d303c6e6100528dc01a0d6cc8f72db498fed5b4b51e3610fef

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d41d65bab3e348b46d5c55d5a2542c1082af31b6008dc8301886d06eda671c5d
MD5 6192613c2592f79a3b8b69c8733bd95c
BLAKE2b-256 647369c723aa5fe1e7cd44d30dc11254c0c4926e8e3a748e00b35787eef89b1a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 2055c12757a9f0e3c075fa6e0fc2193f8b65dffdf44b01284a08ec7ab4a441ce
MD5 7a1a7bee4b24109622c882be6637e287
BLAKE2b-256 2723b6b7065b7b4f96e71c6a38abad742e39b50c274e85e912c7d546f6cdd9b6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 53fb993d71516fe53c49603facc5c0fb671806b26531a2f7ee318939db3e0132
MD5 2ad68a6691be16a62ae746d0129898c5
BLAKE2b-256 bf6c72334c202aa838ba3a08eade38662c9d075e8fc34e4983a9918fd1fe4a32

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5f5daf869775553cae58538ed4bce13429c98d1def228a6b84bdac4787effd05
MD5 6d1896d206ce892f562aa5fb9d94bae3
BLAKE2b-256 ee7cafe316752186a8c00fae2a0c93d36dd7edb5c9e81d7a1aede9fde55d29bc

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 7fe057df2e458ccb299bcd26bc18ed20a3b3a60140c335e52e30fcad03e6b073
MD5 09321310b31f099a6fe560822f3f77de
BLAKE2b-256 38692eb5db050c96a874db1f5cacae541e76119046d0141d1b7ddce0d3bbb8d2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ba1cdb892d56ad391094860a983a59d7aeed63066075fc5c9313da7b2b6b21ec
MD5 fd6540f056cb10d03318293c527cb2f8
BLAKE2b-256 1ef6d5e431607c586ca8f8db98a3a972c5ff00745e25368356bb8e6f3b2a2c47

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 05329b4cccc32cf6cd4cffae2f68fc37f329e17e54c945dfbdac27417ec3653b
MD5 95899975ac4a510a08dd0ba872d3d1b1
BLAKE2b-256 8e165bed9dded804363a53b6af7ac1d4067fa664957e33ca628d40ecbfeb752c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c5a31e2cb18d21df4ee579f975f41f41f53848cb5f35d39c2c89c116326e9b85
MD5 4931eff7d361986a0f0406efcf2f2ca2
BLAKE2b-256 b98c0f5dbb29ce4bb8ba281cecb194cd4e59183651508b08d1810b1f80dc4937

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 94453f65d68bb8d27a60fd4e2b3e96c32bf7dac830e4b081d31addf8af4e4419
MD5 651f35bbdcd1ef359527f894097c4ea7
BLAKE2b-256 2631fab99b4c28279880385fc1133b8d96aca326455bfe68eb904ba2249d9fed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 575bb6d22299219c5ed9fbf9b7a54a693f60cb5a6b6b85ccb411191b0e37f2a9
MD5 8d72d2553955a4e92e74e1519ac6a097
BLAKE2b-256 8986927ce4775e629ae2248c39a409a2cd65f4b6e044a7d7592456f25ca83b63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 4d6e64f38374c115b2082ed6ba73dc607bf9497fd0026dc4a59c2963c1f590a1
MD5 166a84f6a4908a6c4944e488c93160de
BLAKE2b-256 f6bce5c19c5b1307870e4a635a5885a8a0348533d08efc966664dbbf45401ee8

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 50f3fa3487602e594acbc68413fd6a6ead307b1f8e79a82ed4ebb4d745b45b7b
MD5 0b506044c911b7c3f880d6bba75f10ad
BLAKE2b-256 0593494104f7d0cfaeb3417faccf1296ac715efa66886b7bcb355e038f070637

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 f0cde878b7b2fe6c5b663fc127fbf728a5b27670ea5e7b8138b56cc3c79265c3
MD5 118e77296b1d93527b3469930f5018d1
BLAKE2b-256 8a2d68e24a3fa0595b05289ac3d324cc7a7c0fc44fbae9e0b0094118de628cc8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 d5fb4ad0a0553599f1fa3c1aea015c0dba2b1c22e31dc59a9918c47f32cccdac
MD5 091caf91440048835762cd3fca80af94
BLAKE2b-256 7a4f3abe2bcca29977a02db026166254f356e6a0b163077e2db75daa013bcdcb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 31374d6bcdf94db16c1608ee4673dea9711d533f266f03e640bf174c81030793
MD5 b1f4274a32194c240199337816083964
BLAKE2b-256 d09be09e20414d497abb266a5a1b9c4011b52cd72b8841571ccfa34a799c3f7b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4b4ffb43859c56f0bf4d012dc1e4cc9c58a719d18a5990363b4bddea421a2523
MD5 b2b52645db9dadb68ec229f0aa8351bf
BLAKE2b-256 4d996be5318c31060f6c6742b34191349889ce30c6411d20da72dec7ddad4054

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 a5ada403e60846c1296b5f303265edaf7e32b6101e30a0a184b6a8aeb30649a0
MD5 bb8f601e19392eff2203b58f7391857e
BLAKE2b-256 4cc44375b52616281ccc78c43165db44193598f5fcc8831f18732417dc98366d

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 5e4cc805cf7b3e7ddaa7f0003d4d135d72930988628f9760f64abdb3cf48f79d
MD5 9db0af80228e148a7ba5e2d54ffff2d2
BLAKE2b-256 d2884ba42fb9231f8d3c28e0b4b395dd73614c200606cb5c076c433ce976c5f5

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 735321056799306c29033d52fb7c833fe1bdcf4014aa654497570fdc94de7cd9
MD5 d7da573bfec78d1defcaef3cd3128ac6
BLAKE2b-256 8ec8d67a82937d2c63131d5dd4811b0732043ce4989470948f4e5d0c04475fd0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 22611c254e549e17fdd26473e91c60b6ca58b61cc7a8d5af7898598249410215
MD5 68e8ccea8758a5dee9fc3f9045e8de3d
BLAKE2b-256 5b7d79206ff6e1b395c254239ea64a88231fe78e4e60bc90b42a10390253be9d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 95d5691a197c475ae896444c6c68013e796eff10e98bb84d86b9b73ed3327b19
MD5 c414b208e80a38a1d9c380eda7556480
BLAKE2b-256 61d819f3a9ce80169a96ca92b29fe67d65cf4bab18c452bf927ab2103e9fcff6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 dcbeb563fe35c55471fa2b14f20b9d3cc1173683b7afbb2b25e271eaff9cf132
MD5 2fa6b5335729233470fbac2a0b0b3b14
BLAKE2b-256 f24c95dbc92a725a498db361c610a2ab74c38b53749224331b353dd5a9a2b928

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 921130b280f89d342744366a2d04e1d9f39eaa5a579397d7d905dc5ca1a2cf42
MD5 c121e7f0662725b4b341d0334299cfe3
BLAKE2b-256 fcbe096ff5cb3cc5399ad41f7d8e914015cdb75a1da0e8bb97aef01fe8bb3d62

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 ed5f18edf666c5f5dcfbee060303fb3e2e81e26c479f8eed1311ca9fe386c385
MD5 b2bdce5d49f482531b7c833d9e047e9e
BLAKE2b-256 ce2d9de5319086ece0cfb700c70864cb9ea0a0cae1c8812e2d7c33949ba3d6c1

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 9c7ebf12618d9152ea74338d0df6068af9880e76f50f0024632d696d8b0151bd
MD5 4c92eb09357734df6977192a5027e78c
BLAKE2b-256 37be28a0e3bfdc7e06e21c33c00d95b604f1a4bf9552860c08ea0b44358fa997

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 dffabc1371e8f653c600dedb5cd5ae560df26e1bb5042bb2905031eb281bbf72
MD5 848aa3edc8270fdc36d534e489e2101b
BLAKE2b-256 7a56c826993710256d80177c5b39b76326b486c06af13669addeced9868a08cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 60a75ea352f5294782a54bc655685b4e7c993175f891bb0491d42649b8ccf06c
MD5 2d4c9284070920c71590421812dace41
BLAKE2b-256 85404f28a4f098c55ec85e00767f1b5096a464edd525b8aa3fa7996a8037bf0a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 02bee3033bbaf2be17871820f7a8f6fb89bc4ebd759f0d0524a156d50dcfa488
MD5 d54ca55ad28a2a436690417fd8aaa32b
BLAKE2b-256 ece7caa741e25ad1654b615628d8a7b4a5c65103d0528105f8a4f0236f9f4bde

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1114699118399abbfa6f8b2c32f675d80783156fec4696e98a69020f9adcbbec
MD5 0e76209c3727cbd90587767f57893779
BLAKE2b-256 222e3d247937bbaaabc71bae3889eb0f2b61e9389bc5bf3d96b29aa05ad4f2c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 b04ac188629e5d43021e8c553762b7ce1530f7ca4f003a52b8252d7f6fb5bc53
MD5 e525cab5fbd080d241c6b19ecd254797
BLAKE2b-256 ce5b4dda21fcd051c7c69f909a1dd4796fa9de2119b3b4aa3ae8a2b46f7bd1d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 470ef32e2e0d4ffe97d015734fa52c2cc5c91cbb5e3dc472d08c44f3347c7881
MD5 f74bce82201054e557e24bf6107062d2
BLAKE2b-256 21634421ea3806f3533367823dcf752fe1ebd6ebcadb41b3f91e5fa751226b58

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 a6f9895d8f8281c5d1fb5c7660d8beb30c7c475f62c9812c362a9b5b52f84ef7
MD5 85fb400eb8c46aeb20d88afe0c01933e
BLAKE2b-256 3a0ce7adafdfda9c84f12b52d03761ec761ce646e2d77b73cc23fb86891d9f54

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 c21003688c714956ca53d011e148d28e60817c7f0e2cde9c11287d26beee7d3f
MD5 ef74c1bf65bbb61204bedef889cea28b
BLAKE2b-256 f00a242f0fede3a1ad085d9df8102f60895cec10ae25ff6be79a1db9609c34fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 36291ab4757689d14a6e8ca94a6b77423b4488c12f11fd61afb9514266a1df45
MD5 4be41eb97ee80bf7fd2b6167bc545c87
BLAKE2b-256 8d2e39b7c13e45b45465169b376f3561ea73e51fe8b6bf3f765aa176ee2306b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 7728e61016678d0910a907ab084f0bf4d626f7cc0df4f2cf78f9b55ba65f44bb
MD5 f5d5f498fca014ce5be0fefd2ca2cc3a
BLAKE2b-256 8fed45930011949bea336193af2267f326c10ca76c998414a9767b2568f1cfc2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7d7c45ef8e3e8db571d3271cb72cebafb20625b5beb41c9f00084a4294a45a53
MD5 8b2bc8b8b45dd2dd2823d85b21da0270
BLAKE2b-256 0941aefa5e65778b14b762740d3a78e0c955ce21fbb0605b2d68a6b0580e05e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 27f6729cb5858f25ffb8b82870eb559e1548f02864a90a41880488cc6f8dc879
MD5 6fb91f01c69aca324d904f46219878be
BLAKE2b-256 e271eaf4b103d230330a401150b8bfc6c531f35ed4c22d0f07bba50ba0393baa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.0.31b1-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d42709285cfaeccd9c77f194722f8a989f0ca5555c6562da4b2606b6dbd1c4eb
MD5 3529fff5edd0c3c05de4dfee8bf5580f
BLAKE2b-256 01fc8298d6c2d25a747f269a572e23084b1fc2789f5d92f4a0e68b39b671996b

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