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