reed_solomon/lib.rs
1//! Reed-Solomon BCH encoder and decoder suitable for `no_std` environment.
2//!
3//! This library implements block encoder and decoder: error correction code is appended to original data.
4//!
5//! # Example
6//! ```rust
7//! extern crate reed_solomon;
8//!
9//! use reed_solomon::Encoder;
10//! use reed_solomon::Decoder;
11//!
12//! fn main() {
13//! let data = b"Hello World!";
14//!
15//! // Length of error correction code
16//! let ecc_len = 8;
17//!
18//! // Create encoder and decoder with
19//! let enc = Encoder::new(ecc_len);
20//! let dec = Decoder::new(ecc_len);
21//!
22//! // Encode data
23//! let encoded = enc.encode(&data[..]);
24//!
25//! // Simulate some transmission errors
26//! let mut corrupted = *encoded;
27//! for i in 0..4 {
28//! corrupted[i] = 0x0;
29//! }
30//!
31//! // Try to recover data
32//! let known_erasures = [0];
33//! let recovered = dec.correct(&mut corrupted, Some(&known_erasures)).unwrap();
34//!
35//! let orig_str = std::str::from_utf8(data).unwrap();
36//! let recv_str = std::str::from_utf8(recovered.data()).unwrap();
37//!
38//! println!("message: {:?}", orig_str);
39//! println!("original data: {:?}", data);
40//! println!("error correction code: {:?}", encoded.ecc());
41//! println!("corrupted: {:?}", corrupted);
42//! println!("repaired: {:?}", recv_str);
43//! }
44//! ```
45//!
46//! # Unsafe
47//! This library uses some slices indexind that is boundary checked.
48//!
49//! You can disable checks with library feature `unsafe_indexing`,
50//! then unsafe `Slice::get_inchecked()` would be utilized to improve speed where unchecked indexing
51//! is considered safe and LLVM cannot drop boundary checks.
52//!
53//! # Bandwidth
54//! Software implementation is relatively slow because general purpose processors do not support
55//! Galois field arithmetic operations. For example, Galois field multiply requires test for 0,
56//! two table look-ups, modulo add, and anti-log table look-up.
57//!
58//! Besides this performance bound, current implementation is not very optimal
59//! and performs some unnecessary memcpys.
60//!
61//! Encoder bandwidth using one Sandy Bridge core operating on 2.8 `GHz`:
62//! <style type="text/css">
63//! .tg {border-collapse:collapse;border-spacing:0;border-color:#ccc;}
64//! .tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#fff;}
65//! .tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#f0f0f0;}
66//! .tg .tg-baqh{text-align:center;vertical-align:top}
67//! </style>
68//! <table class="tg">
69//! <tr>
70//! <th class="tg-baqh">data<br></th>
71//! <th class="tg-baqh">ecc</th>
72//! <th class="tg-baqh">bandwidth<br></th>
73//! </tr>
74//! <tr>
75//! <td class="tg-baqh">251</td>
76//! <td class="tg-baqh">4</td>
77//! <td class="tg-baqh">115.20 MB/s<br></td>
78//! </tr>
79//! <tr>
80//! <td class="tg-baqh">239</td>
81//! <td class="tg-baqh">16</td>
82//! <td class="tg-baqh">37.76 MB/s<br></td>
83//! </tr>
84//! <tr>
85//! <td class="tg-baqh">223</td>
86//! <td class="tg-baqh">32</td>
87//! <td class="tg-baqh">19.59 MB/s<br></td>
88//! </tr>
89//! </table>
90//!
91//! Decoder bandwidth using one Sandy Bridge core operating on 2.8 `GHz`:
92//! <style type="text/css">
93//! .tg {border-collapse:collapse;border-spacing:0;border-color:#ccc;}
94//! .tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#fff;}
95//! .tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#f0f0f0;}
96//! .tg .tg-uqo3{background-color:#efefef;text-align:center;vertical-align:top}
97//! .tg .tg-baqh{text-align:center;vertical-align:top}
98//! </style>
99//! <table class="tg">
100//! <tr>
101//! <th class="tg-baqh">data<br></th>
102//! <th class="tg-baqh">ecc</th>
103//! <th class="tg-baqh">errors</th>
104//! <th class="tg-baqh">bandwidth</th>
105//! </tr>
106//! <tr>
107//! <td class="tg-uqo3">251</td>
108//! <td class="tg-uqo3">4</td>
109//! <td class="tg-uqo3">0<br></td>
110//! <td class="tg-uqo3">49 MB/s<br></td>
111//! </tr>
112//! <tr>
113//! <td class="tg-baqh"><br></td>
114//! <td class="tg-baqh"><br></td>
115//! <td class="tg-baqh">1</td>
116//! <td class="tg-baqh">16.91 MB/s<br></td>
117//! </tr>
118//! <tr>
119//! <td class="tg-baqh"><br></td>
120//! <td class="tg-baqh"></td>
121//! <td class="tg-baqh">2</td>
122//! <td class="tg-baqh">15.90 MB/s<br></td>
123//! </tr>
124//! <tr>
125//! <td class="tg-uqo3">239</td>
126//! <td class="tg-uqo3">16</td>
127//! <td class="tg-uqo3">0</td>
128//! <td class="tg-uqo3">10.75 MB/s<br></td>
129//! </tr>
130//! <tr>
131//! <td class="tg-baqh"></td>
132//! <td class="tg-baqh"></td>
133//! <td class="tg-baqh">1</td>
134//! <td class="tg-baqh">4.86 MB/s<br></td>
135//! </tr>
136//! <tr>
137//! <td class="tg-baqh"></td>
138//! <td class="tg-baqh"></td>
139//! <td class="tg-baqh">8</td>
140//! <td class="tg-baqh">3.81 MB/s<br></td>
141//! </tr>
142//! <tr>
143//! <td class="tg-uqo3">223</td>
144//! <td class="tg-uqo3">32</td>
145//! <td class="tg-uqo3">0</td>
146//! <td class="tg-uqo3">4.80 MB/s<br></td>
147//! </tr>
148//! <tr>
149//! <td class="tg-baqh"></td>
150//! <td class="tg-baqh"></td>
151//! <td class="tg-baqh">1</td>
152//! <td class="tg-baqh">2.32 MB/s<br></td>
153//! </tr>
154//! <tr>
155//! <td class="tg-baqh"></td>
156//! <td class="tg-baqh"></td>
157//! <td class="tg-baqh">16</td>
158//! <td class="tg-baqh">1.82 MB/s<br></td>
159//! </tr>
160//! </table>
161
162#![cfg_attr(feature = "dev", feature(plugin))]
163#![cfg_attr(feature = "dev", plugin(clippy))]
164#![warn(missing_docs, missing_debug_implementations,
165 trivial_casts, trivial_numeric_casts,
166 unstable_features)]
167
168#![no_std]
169
170const POLYNOMIAL_MAX_LENGTH: usize = 256;
171
172#[macro_use]
173mod macros;
174mod gf;
175mod encoder;
176mod decoder;
177mod buffer;
178
179pub use encoder::Encoder;
180pub use decoder::Decoder;
181pub use decoder::DecoderError;
182pub use buffer::Buffer;