1use crate::gf::poly::Polynom;
2use crate::buffer::Buffer;
3use crate::err::{invalid_combined_len, invalid_data_len, invalid_ecc, invalid_symbol, UsageError};
4use crate::gf;
5
6pub const ENCODER_0: Encoder = Encoder::new(polynom![1]);
8
9pub const ENCODER_1: Encoder = Encoder::new(polynom![1, 1]);
11
12pub const ENCODER_2: Encoder = Encoder::new(polynom![1, 3, 2]);
14
15pub const ENCODER_3: Encoder = Encoder::new(polynom![1, 7, 14, 8]);
17
18pub const ENCODER_4: Encoder = Encoder::new(polynom![1, 15, 19, 23, 10]);
20
21pub const ENCODER_5: Encoder = Encoder::new(polynom![1, 31, 24, 15, 24, 17]);
23
24pub const ENCODER_6: Encoder = Encoder::new(polynom![1, 26, 20, 24, 14, 6, 31]);
26
27pub const ENCODER_7: Encoder = Encoder::new(polynom![1, 16, 11, 4, 5, 5, 6, 24]);
29
30pub const ENCODER_8: Encoder = Encoder::new(polynom![1, 4, 12, 12, 31, 11, 8, 15, 22]);
32
33pub const ENCODER_9: Encoder = Encoder::new(polynom![1, 9, 29, 26, 9, 4, 24, 8, 23, 5]);
35
36pub const ENCODER_10: Encoder = Encoder::new(polynom![1, 19, 9, 21, 10, 16, 31, 26, 25, 21, 29]);
38
39pub const ENCODER_11: Encoder = Encoder::new(polynom![1, 2, 2, 24, 8, 11, 2, 3, 31, 5, 31, 30]);
41
42pub const ENCODER_12: Encoder = Encoder::new(polynom![1, 5, 12, 22, 10, 22, 22, 13, 22, 18, 4, 9, 16]);
44
45pub const ENCODER_13: Encoder = Encoder::new(polynom![1, 11, 31, 20, 16, 21, 12, 23, 26, 8, 3, 20, 1, 27]);
47
48pub const ENCODER_14: Encoder = Encoder::new(polynom![1, 23, 5, 2, 28, 6, 28, 19, 23, 29, 24, 21, 13, 7, 9]);
50
51pub const ENCODER_15: Encoder = Encoder::new(polynom![1, 10, 31, 4, 3, 13, 24, 24, 22, 7, 14, 5, 8, 18, 16, 14]);
53
54pub const ENCODER_16: Encoder = Encoder::new(polynom![1, 21, 7, 22, 16, 9, 23, 29, 19, 9, 25, 14, 4, 17, 13, 8, 11]);
56
57pub const ENCODER_17: Encoder = Encoder::new(polynom![1, 14, 19, 29, 12, 5, 10, 26, 1, 13, 4, 31, 18, 18, 26, 22, 13, 14]);
59
60pub const ENCODER_18: Encoder = Encoder::new(polynom![1, 29, 26, 21, 13, 15, 31, 21, 22, 30, 29, 25, 16, 9, 1, 1, 16, 23, 9]);
62
63pub const ENCODER_19: Encoder = Encoder::new(polynom![1, 30, 24, 30, 23, 24, 14, 17, 12, 1, 26, 27, 30, 28, 26, 2, 19, 2, 21, 27]);
65
66pub const ENCODER_20: Encoder = Encoder::new(polynom![1, 24, 22, 4, 25, 5, 20, 16, 5, 12, 28, 13, 14, 18, 24, 20, 31, 7, 25, 10, 16]);
68
69pub const ENCODER_21: Encoder = Encoder::new(polynom![1, 20, 7, 23, 12, 24, 13, 27, 27, 21, 6, 9, 24, 16, 30, 5, 20, 23, 24, 23, 7, 30]);
71
72pub const ENCODER_22: Encoder = Encoder::new(polynom![1, 12, 17, 21, 23, 9, 10, 18, 17, 31, 8, 19, 30, 23, 7, 24, 3, 1, 3, 16, 28, 28, 29]);
74
75pub const ENCODER_23: Encoder = Encoder::new(polynom![1, 25, 22, 23, 11, 26, 6, 4, 9, 29, 2, 10, 19, 8, 20, 28, 13, 27, 22, 10, 11, 12, 13, 5]);
77
78pub const ENCODER_24: Encoder = Encoder::new(polynom![1, 22, 5, 27, 8, 28, 4, 3, 16, 5, 8, 20, 26, 18, 3, 14, 8, 26, 27, 6, 2, 10, 3, 4, 22]);
80
81pub const ENCODER_25: Encoder = Encoder::new(polynom![1, 8, 29, 18, 18, 23, 14, 20, 23, 19, 1, 31, 27, 22, 12, 9, 13, 17, 31, 28, 12, 19, 17, 3, 1, 24]);
83
84pub const ENCODER_26: Encoder = Encoder::new(polynom![1, 17, 11, 31, 12, 9, 2, 30, 21, 31, 6, 6, 1, 7, 25, 20, 2, 21, 15, 6, 24, 14, 22, 19, 15, 1, 31]);
86
87pub const ENCODER_27: Encoder = Encoder::new(polynom![1, 6, 14, 10, 29, 22, 28, 21, 19, 12, 23, 27, 28, 16, 19, 24, 6, 30, 28, 5, 5, 21, 2, 28, 1, 2, 8, 17]);
89
90pub const ENCODER_28: Encoder = Encoder::new(polynom![1, 13, 17, 7, 25, 7, 2, 15, 16, 16, 12, 14, 18, 10, 18, 4, 21, 1, 16, 31, 7, 23, 1, 10, 27, 9, 30, 3, 10]);
92
93pub const ENCODER_29: Encoder = Encoder::new(polynom![1, 27, 20, 19, 20, 18, 15, 6, 28, 18, 14, 29, 8, 1, 26, 15, 7, 7, 6, 29, 9, 26, 14, 28, 19, 21, 9, 27, 21, 8]);
95
96pub const ENCODER_30: Encoder = Encoder::new(polynom![1, 18, 9, 22, 11, 23, 25, 30, 15, 21, 24, 12, 6, 3, 19, 27, 31, 29, 28, 14, 7, 17, 26, 13, 20, 10, 5, 16, 8, 4, 2]);
98
99#[derive(Debug, Copy, Clone)]
101pub struct Encoder {
102 generator: Polynom,
103}
104
105impl Encoder {
106 const fn new(generator: Polynom) -> Self {
107 Encoder { generator }
108 }
109
110 pub fn encode(&self, data: &[u8]) -> Result<Buffer, UsageError> {
128 if data.len() > 31 {
129 return Err(invalid_data_len());
130 }
131 if data.len() + self.generator.len() - 1 > 31 {
132 return Err(invalid_combined_len());
133 }
134 if data.iter().any(|&x| x > 31) {
135 return Err(invalid_symbol());
136 }
137
138 let mut data_out = Polynom::from(data);
139 let data_len = data.len();
140
141 data_out.set_length(data_len + self.generator.len() - 1);
142
143 let gen = self.generator;
144 let mut lgen = Polynom::with_length(self.generator.len());
145 for (i, gen_i) in gen.iter().enumerate() {
146 lgen[i] = gf::LOG[*gen_i as usize];
147 }
148
149 for i in 0..data_len {
150 let coef = data_out[i];
151 if coef != 0 {
152 let lcoef = gf::LOG[coef as usize] as usize;
153 for j in 1..gen.len() {
154 data_out[i + j] ^= gf::EXP[(lcoef + lgen[j] as usize)];
155 }
156 }
157 }
158
159 data_out[..data_len].copy_from_slice(data);
160 Ok(Buffer::from_polynom(data_out, data_len))
161 }
162}
163
164pub fn encode(data: &[u8], ecc: u8) -> Result<Buffer, UsageError> {
180 match ecc {
181 0 => ENCODER_0.encode(data),
182 1 => ENCODER_1.encode(data),
183 2 => ENCODER_2.encode(data),
184 3 => ENCODER_3.encode(data),
185 4 => ENCODER_4.encode(data),
186 5 => ENCODER_5.encode(data),
187 6 => ENCODER_6.encode(data),
188 7 => ENCODER_7.encode(data),
189 8 => ENCODER_8.encode(data),
190 9 => ENCODER_9.encode(data),
191 10 => ENCODER_10.encode(data),
192 11 => ENCODER_11.encode(data),
193 12 => ENCODER_12.encode(data),
194 13 => ENCODER_13.encode(data),
195 14 => ENCODER_14.encode(data),
196 15 => ENCODER_15.encode(data),
197 16 => ENCODER_16.encode(data),
198 17 => ENCODER_17.encode(data),
199 18 => ENCODER_18.encode(data),
200 19 => ENCODER_19.encode(data),
201 20 => ENCODER_20.encode(data),
202 21 => ENCODER_21.encode(data),
203 22 => ENCODER_22.encode(data),
204 23 => ENCODER_23.encode(data),
205 24 => ENCODER_24.encode(data),
206 25 => ENCODER_25.encode(data),
207 26 => ENCODER_26.encode(data),
208 27 => ENCODER_27.encode(data),
209 28 => ENCODER_28.encode(data),
210 29 => ENCODER_29.encode(data),
211 30 => ENCODER_30.encode(data),
212 _ => Err(invalid_ecc()),
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use crate::gf::poly_math::Mul as _;
219 use crate::gf::poly::Polynom;
220 use crate::gf;
221
222 #[test]
223 fn generator_poly() {
224 fn generator_poly(ecclen: usize) -> Polynom {
225 let mut gen = polynom![1];
226 let mut mm = [1, 0];
227 for i in 0..ecclen {
228 mm[1] = gf::pow(2, i as i32);
229 gen = gen.mul(&mm);
230 }
231 gen
232 }
233
234 assert_eq!(&super::ENCODER_0.generator[..], &generator_poly(0)[..]);
235 assert_eq!(&super::ENCODER_1.generator[..], &generator_poly(1)[..]);
236 assert_eq!(&super::ENCODER_2.generator[..], &generator_poly(2)[..]);
237 assert_eq!(&super::ENCODER_3.generator[..], &generator_poly(3)[..]);
238 assert_eq!(&super::ENCODER_4.generator[..], &generator_poly(4)[..]);
239 assert_eq!(&super::ENCODER_5.generator[..], &generator_poly(5)[..]);
240 assert_eq!(&super::ENCODER_6.generator[..], &generator_poly(6)[..]);
241 assert_eq!(&super::ENCODER_7.generator[..], &generator_poly(7)[..]);
242 assert_eq!(&super::ENCODER_8.generator[..], &generator_poly(8)[..]);
243 assert_eq!(&super::ENCODER_9.generator[..], &generator_poly(9)[..]);
244 assert_eq!(&super::ENCODER_10.generator[..], &generator_poly(10)[..]);
245 assert_eq!(&super::ENCODER_11.generator[..], &generator_poly(11)[..]);
246 assert_eq!(&super::ENCODER_12.generator[..], &generator_poly(12)[..]);
247 assert_eq!(&super::ENCODER_13.generator[..], &generator_poly(13)[..]);
248 assert_eq!(&super::ENCODER_14.generator[..], &generator_poly(14)[..]);
249 assert_eq!(&super::ENCODER_15.generator[..], &generator_poly(15)[..]);
250 assert_eq!(&super::ENCODER_16.generator[..], &generator_poly(16)[..]);
251 assert_eq!(&super::ENCODER_17.generator[..], &generator_poly(17)[..]);
252 assert_eq!(&super::ENCODER_18.generator[..], &generator_poly(18)[..]);
253 assert_eq!(&super::ENCODER_19.generator[..], &generator_poly(19)[..]);
254 assert_eq!(&super::ENCODER_20.generator[..], &generator_poly(20)[..]);
255 assert_eq!(&super::ENCODER_21.generator[..], &generator_poly(21)[..]);
256 assert_eq!(&super::ENCODER_22.generator[..], &generator_poly(22)[..]);
257 assert_eq!(&super::ENCODER_23.generator[..], &generator_poly(23)[..]);
258 assert_eq!(&super::ENCODER_24.generator[..], &generator_poly(24)[..]);
259 assert_eq!(&super::ENCODER_25.generator[..], &generator_poly(25)[..]);
260 assert_eq!(&super::ENCODER_26.generator[..], &generator_poly(26)[..]);
261 assert_eq!(&super::ENCODER_27.generator[..], &generator_poly(27)[..]);
262 assert_eq!(&super::ENCODER_28.generator[..], &generator_poly(28)[..]);
263 assert_eq!(&super::ENCODER_29.generator[..], &generator_poly(29)[..]);
264 assert_eq!(&super::ENCODER_30.generator[..], &generator_poly(30)[..]);
265 }
266
267 #[test]
268 fn encode() {
269 let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
270 let ecc = [5, 10, 26, 18, 9, 22, 13, 21];
271
272 let encoded = super::encode(&data[..], ecc.len() as u8).unwrap();
273
274 assert_eq!(data, encoded.data());
275 assert_eq!(ecc, encoded.ecc());
276 }
277}