ReedSolomonEx (reed_solomon_ex v0.2.0)
View SourceReed-Solomon encoder/decoder wrapper using Rust NIF.
Wraps the reed-solomon Rust crate to provide robust
error-correcting codes for binary data. This library is suitable for
transmitting binary packets over noisy links with optional parity.
Examples
iex> {:ok, codeword} = ReedSolomonEx.encode("hello", 4)
iex> {:ok, original} = ReedSolomonEx.correct(codeword, 4)
iex> original == "hello"
trueSchedulers
Codewords are capped at 255 bytes (GF(2^8)), so a single encode or decode is far below the ~1ms threshold that warrants a dirty scheduler. Encoding always runs on a regular scheduler; decoding runs on a regular scheduler for parity sizes up to 32 bytes and falls back to a dirty-CPU scheduler above that, where worst-case decode work on slow cores may exceed 1ms.
This matters on targets where the dirty-CPU run queue is kept busy by other NIFs (e.g. ML inference): a sub-millisecond encode should not queue behind a 100ms+ dirty job.
For many small chunks, prefer encode_batch/3 / correct_batch/3, which
amortize NIF call overhead by looping in Rust. The wrapper slices large
batches so no single regular-scheduler call exceeds the ~1ms budget.
Summary
Functions
Decode/correct a binary codeword and attempts to correct up to N/2 errors.
Decodes/corrects a list of codewords in a single NIF call per slice.
Decode/Correct a binary codeword and attempts to correct up to N/2 errors.
Same as correct/2, but returns the number of errors corrected.
Encodes a binary by appending N parity bytes for error correction.
Encodes a list of binaries in a single NIF call per slice, appending
parity_bytes of parity to each chunk.
Encodes a binary by appending N parity bytes for error correction. As encode/2, except that it only returns the parity bytes.
Check if a given codeword is corrupted (detectable by RS).
Functions
@spec correct(binary(), non_neg_integer(), [byte()] | nil) :: {:ok, binary()} | {:error, any()}
Decode/correct a binary codeword and attempts to correct up to N/2 errors.
Runs on a regular scheduler for parity_bytes <= 32,
on a dirty-CPU scheduler above that.
Parameters
codeword: binary of data + parityparity_bytes: number of parity bytes originally usedknown_erasures: offsets of known erasures (optional)
Returns
{:ok, original_data}on success{:error, reason}if the message cannot be corrected
@spec correct_batch([binary()], non_neg_integer(), keyword()) :: {:ok, [{:ok, binary()} | :error]}
Decodes/corrects a list of codewords in a single NIF call per slice.
Unlike encode_batch/3, failures are per-codeword: a corrupted-beyond-repair
codeword yields :error in its position without failing the batch.
Known erasures are not supported in batch mode; use correct/3 for
codewords with known erasure positions.
Parameters
codewords: list of binaries (data + parity each)parity_bytes: number of parity bytes originally usedopts:slice_size: pos_integer()— codewords per NIF invocation
Returns
{:ok, results}whereresultsis a list of{:ok, binary()} | :error, in input order
@spec correct_err_count(binary(), non_neg_integer(), [byte()] | nil) :: {:ok, {binary(), non_neg_integer()}} | {:error, any()}
Decode/Correct a binary codeword and attempts to correct up to N/2 errors.
Same as correct/2, but returns the number of errors corrected.
Runs on a regular scheduler for parity_bytes <= 32,
on a dirty-CPU scheduler above that.
Parameters
codeword: binary of data + parityparity_bytes: number of parity bytes originally usedknown_erasures: offsets of known erasures (optional)
Returns
{:ok, {original_data, err_count}}on success{:error, reason}if the message cannot be corrected
@spec encode(binary(), non_neg_integer()) :: {:ok, binary()} | {:error, any()}
Encodes a binary by appending N parity bytes for error correction.
Runs on a regular scheduler: input is capped at 255 bytes total, so the work is always sub-millisecond.
Parameters
data: binary to encodeparity_bytes: number of bytes to use as parity (must be >= 2)
Returns
{:ok, binary}with appended parity{:error, reason}on failure
@spec encode_batch([binary()], non_neg_integer(), keyword()) :: {:ok, [binary()]} | {:error, any()}
Encodes a list of binaries in a single NIF call per slice, appending
parity_bytes of parity to each chunk.
Equivalent to Enum.map(chunks, &encode(&1, parity_bytes)) but far cheaper
when encoding many small chunks: one NIF round-trip covers a whole slice of
chunks and the Reed-Solomon generator polynomial is computed once.
The chunk list is internally sliced so that no single NIF invocation
exceeds the ~1ms regular-scheduler budget, even on slow cores. The slice
size scales inversely with parity_bytes (32 chunks per call at parity 8)
and can be overridden with the :slice_size option.
Parameters
chunks: list of binaries to encode (eachbyte_size(chunk) + parity_bytes <= 255)parity_bytes: number of bytes to use as parity (must be >= 2)opts:slice_size: pos_integer()— chunks per NIF invocation
Returns
{:ok, [binary()]}encoded codewords, in input order{:error, reason}if any chunk is oversized (reports the failing chunk index)
@spec encode_ecc(binary(), non_neg_integer()) :: {:ok, binary()} | {:error, any()}
Encodes a binary by appending N parity bytes for error correction. As encode/2, except that it only returns the parity bytes.
@spec is_corrupted(binary(), non_neg_integer()) :: {:ok, boolean()} | {:error, any()}
Check if a given codeword is corrupted (detectable by RS).