rlnc/
lib.rs

1//! # rlnc: Random Linear Network Coding
2//!
3//! `rlnc` is a Rust library that provides an implementation of Random Linear Network Coding (RLNC)
4//! over finite field GF(2^8). RLNC is a technique where data is split into smaller pieces, treated
5//! as vectors over GF(2^8). Source node in a network creates encoded packets by computing random
6//! linear combinations of those pieces using randomly sampled coefficients. These encoded packets,
7//! tagged with coefficient information, often called coded pieces, are forwarded to peers.
8//! Intermediate nodes in the network can combine any number of coded pieces to create new coded pieces.
9//! Receiving nodes decode the original data by collecting senough independent combinations to solve the
10//! linear system of equations. RLNC enhances network throughput, robustness, and efficiency, particularly
11//! in lossy or dynamic networks. It’s used in applications like video streaming, distributed storage, and
12//! satellite communications, improving reliability and reducing latency.
13//!
14//! ## How it Works
15//!
16//! At its core, RLNC works by combining original data pieces into new "coded pieces"
17//! using random linear combinations over GF(2^8).
18//!
19//! The main components of this library are:
20//!
21//! -   **`Encoder`**: Takes the original data, splits it into fixed-size pieces,
22//!     and generates new coded pieces by applying random linear combinations.
23//!     Each coded piece includes a coding vector and the linearly combined data.
24//!     The encoder handles necessary padding and a boundary marker to ensure
25//!     correct decoding and data recovery.
26//!
27//! -   **`Recoder`**: A crucial feature of network coding. A recoder takes
28//!     already coded pieces as input and generates *new* coded pieces from them.
29//!     This allows intermediate nodes in a network to re-encode data without
30//!     first decoding it to the original form, significantly improving
31//!     throughput and robustness in complex network topologies.
32//!
33//! -   **`Decoder`**: Receives coded pieces and attempts to reconstruct the
34//!     original data. It uses Gaussian elimination to maintain a matrix of
35//!     received pieces. As soon as enough linearly independent pieces are received,
36//!     it can reconstruct the original data, regardless of which specific pieces were lost or received.
37//!
38//! ## Features
39//!
40//! -   **Flexible data handling**: Supports arbitrary byte lengths for input
41//!     data, with internal padding and boundary markers for robust decoding.
42//! -   **Error Handling**: Comprehensive `RLNCError` enum for various failure scenarios.
43//!
44//! ## Example Usage
45//!
46//! A typical workflow involves creating an `Encoder` with your original data,
47//! generating coded pieces, sending them across a network (potentially through `Recoder`s),
48//! and finally, using a `Decoder` to reconstruct the original data.
49//!
50//! ```rust
51//! use rand::Rng;
52//! use rlnc::{
53//!     RLNCError,
54//!     full::{decoder::Decoder, encoder::Encoder},
55//! };
56//!
57//! let mut rng = rand::rng();
58//!
59//! // 1. Define original data parameters
60//! let original_data_len = 1024 * 10; // 10 KB
61//! let piece_count = 32; // Data will be split into 32 pieces
62//! let original_data: Vec<u8> = (0..original_data_len).map(|_| rng.random()).collect();
63//! let original_data_copy = original_data.clone();
64//!
65//! // 2. Initialize the Encoder
66//! let encoder = Encoder::new(original_data, piece_count).expect("Failed to create RLNC encoder");
67//!
68//! // 3. Initialize the Decoder
69//! let mut decoder = Decoder::new(encoder.get_piece_byte_len(), encoder.get_piece_count()).expect("Failed to create RLNC decoder");
70//!
71//! // 4. Generate coded pieces and feed them to the decoder until decoding is complete
72//! while !decoder.is_already_decoded() {
73//!     let coded_piece = encoder.code(&mut rng);
74//!     match decoder.decode(&coded_piece) {
75//!         Ok(_) => {}, // Piece was useful
76//!         Err(RLNCError::PieceNotUseful) => {}, // Piece was not useful (linearly dependent)
77//!         Err(RLNCError::ReceivedAllPieces) => break, // Already decoded
78//!         Err(e) => panic!("Unexpected error during decoding: {e:?}"),
79//!     }
80//! }
81//!
82//! // 5. Retrieve the decoded data
83//! let decoded_data = decoder.get_decoded_data().expect("Failed to retrieve decoded data even after all pieces are received");
84//!
85//! // 6. Verify that the decoded data matches the original data
86//! assert_eq!(original_data_copy, decoded_data);
87//! println!("RLNC workflow completed successfully! Original data matches decoded data.");
88//! ```
89//!
90//! ## Installation
91//!
92//! Add this to your `Cargo.toml`:
93//!
94//! ```toml
95//! [dependencies]
96//! rlnc = "=0.3.0" # Use the latest version
97//! rand = "=0.9.1" # Required for random number generation
98//! ```
99//!
100//! For more see README in `rlnc` repository @ <https://github.com/itzmeanjan/rlnc>.
101
102mod common;
103
104pub mod full;
105pub use crate::common::errors::RLNCError;