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.1.0b1.tar.gz (379.0 kB view details)

Uploaded Source

Built Distributions

reedsolo-2.1.0b1-pp39-pypy39_pp73-win_amd64.whl (502.4 kB view details)

Uploaded PyPy Windows x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

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

Uploaded PyPy macOS 10.9+ x86-64

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

Uploaded PyPy Windows x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

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

Uploaded PyPy macOS 10.9+ x86-64

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

Uploaded PyPy Windows x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ x86-64

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

Uploaded PyPy manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

reedsolo-2.1.0b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (501.2 kB view details)

Uploaded PyPy macOS 10.9+ x86-64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

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

Uploaded CPython 3.11 musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.11 musllinux: musl 1.1+ i686

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

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.1.0b1-cp311-cp311-macosx_10_9_x86_64.whl (538.4 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

reedsolo-2.1.0b1-cp310-cp310-win_amd64.whl (514.6 kB view details)

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

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

Uploaded CPython 3.10 musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.10 musllinux: musl 1.1+ i686

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

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.1.0b1-cp310-cp310-macosx_10_9_x86_64.whl (537.8 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

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

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

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

Uploaded CPython 3.9 musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.9 musllinux: musl 1.1+ i686

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

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.1.0b1-cp39-cp39-macosx_10_9_x86_64.whl (538.3 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

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

Uploaded CPython 3.8 Windows x86-64

reedsolo-2.1.0b1-cp38-cp38-win32.whl (485.7 kB view details)

Uploaded CPython 3.8 Windows x86

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

Uploaded CPython 3.8 musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.8 musllinux: musl 1.1+ i686

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

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

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

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

reedsolo-2.1.0b1-cp38-cp38-macosx_10_9_x86_64.whl (542.5 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

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

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

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

Uploaded CPython 3.7m musllinux: musl 1.1+ x86-64

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

Uploaded CPython 3.7m musllinux: musl 1.1+ i686

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

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

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

Uploaded CPython 3.7m manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

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

Uploaded CPython 3.7m macOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1.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.1.0b1.tar.gz
Algorithm Hash digest
SHA256 e11528d63e75461d45b86c23f9db8260303d6ab6cae075fa9eddb44527ad8ece
MD5 1740d00059fa0a0b468816f0602c3c23
BLAKE2b-256 3a6e3b9c1908553558f365edce2c8a4e43a4a857e19f10eb0e8e313fe9c88b80

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp39-pypy39_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 7ac00c115a5e6103a9332650c14464651664b2d7f2fbb89f6d3aea91d14a9ffd
MD5 155c8edc551f143c89aad509a796731a
BLAKE2b-256 4b838e3e8e43c66e1659cee3e7ef6bafee7b6df35efaec9b2017898e950b5738

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 67b3705f9dfee7a61a86090eb789f4ebccade800bfb5b0e2a51e81a4e5ebd2a1
MD5 9936b08140d0706a5126a1085f6899c8
BLAKE2b-256 af9a5c22d830b270d3d7ea18a3a03d57d325744c5f94b8aec6ae22c4374470c6

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.0b1-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.0b1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 18f6e19794924f028463bdd56a56e9788ffe8b03b0ad87c88c82e23425dd423c
MD5 620c50c33cbc88afc11f09f2857c2f84
BLAKE2b-256 8a1a2375e550a126b07dce9beec7bc57298e15298d8344789b02fb02355ab7c2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 3e9991a8cd3df3fca61eaeff9f81bfb624e70ac0eea13a5dacde57e1462bee50
MD5 c51e5b76819da42b16e0e3d5707aed58
BLAKE2b-256 786cc32ce21743bc272b31eafbb7b5799d501f316d41ab1d8c9aa4b063b2c84f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp38-pypy38_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 6d43d1462cf87c4d01eeab2899c1aa0372548bed6f4b33b09b5f55e2b550d65f
MD5 10ce049fabfda77e35429c28e4dc35af
BLAKE2b-256 147a4bfa48d1a4a66b24ac73838662cf009a13f14ba06e79c8877fe0c74eaadb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6b2bf76d851da9d9a0be7946c05f67297378a90e792fc206c45ada3103bcc192
MD5 103ed64e44f1119aa069a670489bccad
BLAKE2b-256 1ef0f9dadce646daec1500fc8ee97260775c4ef51d9d31394e8042dc32fed7ea

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.0b1-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.0b1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4facc4f12f749894e69b39a461b5a7833570088063d9020bc7963ba308603597
MD5 f679133a664b31e91d23fba0241db50d
BLAKE2b-256 889edf8f484864d188dc20278e9219152ab738198ebd9a355f9c066258564674

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 f55f4ef1349d144ba5255dff619dbcba6df598f5d93a6489f0ba39be3088d34d
MD5 7a5d07cb1ccaf9e3b1e45bc3f74012da
BLAKE2b-256 43ba7e92e68d4ef406a8d84d9a06d4ad852a9caabb71289f1b8da1aaf82cb2e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 01b559c4b1022d1325b1a85cfe363e8b7d89113b0aa5f24f2b17f269b60fcec0
MD5 8c8ac682b7bcccedd8bfa334cb22b817
BLAKE2b-256 a06c9cdac6b2408929b3b02d64c7554f234c2f13c9df7467b3032835d7a7808c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 eca03ffdf92e50c4d542b1f5712f2983b623319bf248889fd2af4609911b0f4b
MD5 28bea6963c12b92f6ceda44fbf591be5
BLAKE2b-256 3f61cc1f1260982aeed0ba1bf38d4a42127dfd7684734837c119cc9b5d23e268

See more details on using hashes here.

File details

Details for the file reedsolo-2.1.0b1-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.0b1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 627e203f987c1988dd3dc02e8108a4cbc781a26f9ccf89143e834f23644c7d2b
MD5 cbaff712589bb1e00ff5987febfc7624
BLAKE2b-256 fce3b19d8d3348247deb3589c68f50b195c80d0734fcfdb2b7a752437750246b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c0c60337e5a6a31f81b5e6d5c01d2b7c3b6bad713693d12598420c6284995f91
MD5 2519c120c61302b8147fb51158855163
BLAKE2b-256 a6f538cb64bc31132b20b2fb975c00fdaeaf8cbeae2b3e3484ff1465df0b8ada

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 8351a853b8c14bfada42e079d7ec640118054ee069dad7be5adb9dd3ac3ff229
MD5 c894d8c3274f257d7e7fa50168ce43e7
BLAKE2b-256 2b45513c7d7be26a1bf72ec55ef5eab7d53863ca711374c9ca8cfdc255f48dc8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-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.1.0b1-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 acff1e3bc3ebce2a929d2697163da2cfd3510adcf3a61fc72b341f1eb057708d
MD5 ea6bf49bbf4c8b56f6ed94236f68b110
BLAKE2b-256 f2bd532aabafd4a1c81ff588d041f5d0914299d695c6807436f1935e7e09683f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 734da172354c8fe9c9f7c702f5522b93516b3f5cd0b09a69f191bcbd18fecca3
MD5 933d7599c780cf5b128ed64059bcd4e2
BLAKE2b-256 67e2dde758ce0ca95dbb5301fd1d044dcf785764b8160e87596ebf26fdda06a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp311-cp311-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 a0ca9de75d781b31043d376c8c3e168e46f788fb27e2c38f9ccaffeec6a0c636
MD5 17233c117bb14a5abb667224d2457842
BLAKE2b-256 7b770b1a451fe821168d41ac3d18928c1499056b8fab5bf35aa53ae88fc4c769

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c7daf3c6b1fcea6ffd7c1dfbd49f9600bbc1ea0e077d1dbf58186155e0fb4572
MD5 1d95448a28ac82d0e087e2cc0d56b29c
BLAKE2b-256 aaa118a20766092773961e78e58d68e39b9f9cf27d39ba13162e3160ff894431

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f4f3b8c38176a9ed1988f6dee264d2e7d8b0f66676273e53a508abd7f6719af1
MD5 3b10fdac52b237c6ff1a3175b453f335
BLAKE2b-256 308a23957c3dbaf93354d722d178db1c7b5318253a6e57967a649f2d95f59ff5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2b291db0cac3220a4fda1722d8d265d7755b235d6bfe6163d7f2d03d481d21bf
MD5 45e3bc95a575b2bbddf3e531634d0a4d
BLAKE2b-256 909c049525273199277bbdf2a2b30ad8d0bf6922e65c86c542f914cbda9e0db8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 8b9fc4c5360a1fdd7f7a9531f2d98d080fec54acb276ec51a12e258b6ab307d0
MD5 4d53ded30071da9926c449835f8ec078
BLAKE2b-256 9ab3d1f0ea96b60fe7c778ae986261e5c1c5e1506aadc3f574f37f74db65dd4e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-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.1.0b1-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 107b94155fbc5eb561198fa4dd37d3cf5cb6aece73f47454e94be86d24596a64
MD5 f2d9da7e98eb7935c1a4943cc5e1ae45
BLAKE2b-256 ebeb677d258890c2ebd3e489431153668de193ab04e35b4c708fa56b70b8b55b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 0619a8edace476943b7ceb9fef0e74a1f1da26c4e506e58fb7d706ebd1c22c44
MD5 17939d8b4938eaa02b357cd9f3970071
BLAKE2b-256 2af24d62c9232a6695e98619936a93227ac6ac74c4146594c1217596617f64f8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp310-cp310-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 d54f5090dcb9f4baded275bc07c79ef69eca710319c6b2f559c0bae78c14519f
MD5 024eceadda3c149480c9da25e3dffa1e
BLAKE2b-256 a59f62af9774d325ef301168b9c45dd22a3d85b378646264e6d2aedbebec88e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c7867735c9c6c1733675122d86d8bebba78a9ab827411d08733b6d0599d2550a
MD5 148afaa6516786e3ed9f59d735dbe124
BLAKE2b-256 ab8474df51236795a6fe5ff0b00b185f71f0ba3a530c1df1a9bc9e696b3224b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d8f2960f8ccbde255998b27051af0c7343acc77927ead8775d6d5881fafa5a3c
MD5 06db9ee62c237311a34b468281405862
BLAKE2b-256 2519ecda261b087c49fdf08b5a2ca61951ecd4320da5435a9928cb37ab3f3a3d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5a1e436efc4f9a46f7684be5e672c3ecf2f7bf4b18a12954023d52c5ee6fbeb8
MD5 aec56e505080aa9f218c5a84d04db340
BLAKE2b-256 d4231e1a970bc4248a95a4db657d92b2158ebf9cc5ece41d2ea345f72197af1b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-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.1.0b1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 019b674338a7056127131945bf526d3879875f99934902010d069417a5510aea
MD5 e540c402b064e6b8db02e06392a15bea
BLAKE2b-256 d544a2548c8d13df1dc9a7da89c0bfb7b64e4fecb8e5f8046e18550cf988ba65

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-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.1.0b1-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 5352182cde86941c43ee1746d1fe489eb7f5fe1343a9149b03a414c9e82b7e83
MD5 c5f75e703ffead070d55f3970776654b
BLAKE2b-256 c63354fb9c6e0907ada7456888d89f30ec2761db9b33c05c0a28f7c776b9d438

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 4a407662488555e1ba3df2d366bc084865edfad3c8600afd3b686c9a1bd372fe
MD5 1abe77e5e9259a51dc1c4b982bfbb5af
BLAKE2b-256 bbbbea6a8f37b2cf1433cf0fdc50a0eecded38aa2df943f95044868e52759492

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp39-cp39-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 36b96eb1e08a8254d3c29fb317f4c14df13767f4d22700663999d74364cfe813
MD5 51746a5b982cdd04a9f7b22b342280a6
BLAKE2b-256 e4c5a870658051c02e54c5f8b6e812a8664372826b5374aeafd65a555aef3e9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f1a44e0b5f4301da0ff570d83a5964bed1a52b623c268b337aea5d260195b7ae
MD5 5d853e253d0f9b637f07c8bb29e39858
BLAKE2b-256 28947621f27be1d8553237fa23d2688f23996c7ea2c9e9d67a0f491690bed839

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3cb8c867c648f24cbf9ddbd9e1c433cbbbc403fee587cc3b20040e4e0d68e49e
MD5 42cca36920274cd6780a940767ffa01e
BLAKE2b-256 d2167edc51934888e75bfa9d933eaf831adeab289cc73adc0d260b8e6755a3a8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 056ac0836653788265a3a77b7d5c3efcb63b8417477376bc35b47c2601a757e4
MD5 a1612ab39207f7265dab4c45901bedb2
BLAKE2b-256 0bf3ce179ca60d38103e034d6c3575f416aec8c49318846d24317e0ed7a3a706

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-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.1.0b1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 a64d8aa80a4b74b3fc16a662400943e979c75ef961973c4166f00fb63ba6cea5
MD5 57bd67d78cfb2cce85585bafa587819a
BLAKE2b-256 7ef49c01e0b57b9becf6b74da60ae901fef5968891cae9f761598b6036d72375

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-cp38-cp38-win32.whl
  • Upload date:
  • Size: 485.7 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.1.0b1-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 17cfdb64cb19e996705c739835b5add0b7eb944954fabf544100031d4b4fdb07
MD5 7a5f5388faf06d42a73e835826b92d30
BLAKE2b-256 23cc2a495aa5293550b4013bd9cc41768d087ac3893358615a17085ae9c830be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 4b24471b3af9011f4b9291cb49b0d59cb115b8712c0c10109afa3b125e1d0a7f
MD5 8b70bd2f2a210857c335c470ff30a8d7
BLAKE2b-256 693f8df5b5d015882752c85543a432f4ccbbd234bc06960df8fd448ced90168e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp38-cp38-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 ac734947e29fea2d159291ba05f232989dc3e60dd2710a0115dfcff03aaf8c79
MD5 8e8a4967ae279ab0c0bb0c9df0eaee23
BLAKE2b-256 57b52f5c35339738e63039d487f604a9dffd7dbd15a9a7cfdef5c5eb19c74750

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ea453e5a0f417675b88411baeef19ee1627a5da7e500fdb108b7d8d9e8c2335b
MD5 2f78bbc9e6821c7707a0ed6b0ced67bd
BLAKE2b-256 1cc093a408f5a887b8b055c2b52b16a589ed4446e5a2a3473b92cf6a206faabe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 eab08fba12a36f3a8b7144b14614896236a58c1ed3f540fce0c1fe95abb62620
MD5 8077c62270e59ac83259d94c88e6656a
BLAKE2b-256 27c873914693fac63eee9b81e2c73690b8794a7e1ef98642929143d567327b4c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 b45cc45ec4af25f2e12e7104e6f2b6c7c1804313fd9b4cb79a55ecf90c40f078
MD5 333b72f50dee34513d63b97bdd0f10bd
BLAKE2b-256 3cc295e929a449d9523aa3d98f8dd97d455321be7bc1aa5ba680f64ea1f44875

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 1654cfdaa2cebf2ac1ef81bed45a4f53c37d6de9b487cb68652cdf1f75985aa8
MD5 cafd312b0020adf3aca2d21d7ae44b80
BLAKE2b-256 3face46d03109737575a7828550187266d54fdcfa6c873cfd8e5ea31bed6c176

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reedsolo-2.1.0b1-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.1.0b1-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 28b628d946bfc9e50709f5344d3aca081dbb63d5d5aa9f96dd01c84ff3e5d39d
MD5 253a2d1312acb118cbf99ec63d4ce112
BLAKE2b-256 ce8026d284f0c184b81dc1168d11e3f7fa8ec7ffc39a5c1fa5ecb5938a2b562f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 4c64644949226dd7cb361af84026cfb1e79b4f0e0f5925ca47529520a6e603e8
MD5 131a18e9ceb65473e2bcfd510d953463
BLAKE2b-256 d25bd4fc9afc30f83da74c16ed0110dec8964b8cbfad8bc80d8a87abeb16e288

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 bf7130e65562b3d90720766f3e6c0c705966f19847a366a1685a54b225a3409a
MD5 8f283cd2e475b4bfcc1b6b8d487073e8
BLAKE2b-256 e414d7651eb83f6fb413a2d474111d40749db4e267387475e1eb0a6ded1b831b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b07cc699a1631f4352223467d644d112132b81fb6373bbc2cd046beb43b2816a
MD5 e62353e6104f38e386eb510c05670a65
BLAKE2b-256 58ef232baede6682a31de8746a328a5bccc67011d56f369de5f7a7afb5c58726

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 42d1c9bd902a53ec1be27c0efb3224a3479b2877b13e036a38fd26eeaed339e2
MD5 dd6067291253ca3755b214ef89f329b6
BLAKE2b-256 ace7c35a16092fbd1d1994be2cd1f8c8767d806a3715658b5963377e70ea54b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for reedsolo-2.1.0b1-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 98d648dc0a2d285a50464c3f744eedaa89a70f1e8d166553cc045401277bd952
MD5 4e5667b0e0281e64329a34ce0d9972e7
BLAKE2b-256 04011e196f8b6686817642e92032a41e8b239b8044533993c652bf143634ea08

See more details on using hashes here.

Supported by

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