1use crate::gf::poly_math::*;
2use crate::gf::poly::Polynom;
3use crate::buffer::Buffer;
4use crate::err::{CorrectionError, invalid_data_len, invalid_data_len_for_ecc, invalid_ecc, invalid_erase_pos, invalid_symbol, UsageError};
5use crate::gf;
6
7pub const DECODER_0: Decoder = Decoder::new(0);
9
10pub const DECODER_1: Decoder = Decoder::new(1);
12
13pub const DECODER_2: Decoder = Decoder::new(2);
15
16pub const DECODER_3: Decoder = Decoder::new(3);
18
19pub const DECODER_4: Decoder = Decoder::new(4);
21
22pub const DECODER_5: Decoder = Decoder::new(5);
24
25pub const DECODER_6: Decoder = Decoder::new(6);
27
28pub const DECODER_7: Decoder = Decoder::new(7);
30
31pub const DECODER_8: Decoder = Decoder::new(8);
33
34pub const DECODER_9: Decoder = Decoder::new(9);
36
37pub const DECODER_10: Decoder = Decoder::new(10);
39
40pub const DECODER_11: Decoder = Decoder::new(11);
42
43pub const DECODER_12: Decoder = Decoder::new(12);
45
46pub const DECODER_13: Decoder = Decoder::new(13);
48
49pub const DECODER_14: Decoder = Decoder::new(14);
51
52pub const DECODER_15: Decoder = Decoder::new(15);
54
55pub const DECODER_16: Decoder = Decoder::new(16);
57
58pub const DECODER_17: Decoder = Decoder::new(17);
60
61pub const DECODER_18: Decoder = Decoder::new(18);
63
64pub const DECODER_19: Decoder = Decoder::new(19);
66
67pub const DECODER_20: Decoder = Decoder::new(20);
69
70pub const DECODER_21: Decoder = Decoder::new(21);
72
73pub const DECODER_22: Decoder = Decoder::new(22);
75
76pub const DECODER_23: Decoder = Decoder::new(23);
78
79pub const DECODER_24: Decoder = Decoder::new(24);
81
82pub const DECODER_25: Decoder = Decoder::new(25);
84
85pub const DECODER_26: Decoder = Decoder::new(26);
87
88pub const DECODER_27: Decoder = Decoder::new(27);
90
91pub const DECODER_28: Decoder = Decoder::new(28);
93
94pub const DECODER_29: Decoder = Decoder::new(29);
96
97pub const DECODER_30: Decoder = Decoder::new(30);
99
100#[derive(Debug, Copy, Clone)]
102pub struct Decoder {
103 ecc_len: u8,
104}
105
106fn check_message(msg: &[u8], ecc_len: u8) -> Result<(), UsageError> {
107 if msg.len() > 31 {
110 return Err(invalid_data_len());
111 }
112 if msg.len() < ecc_len as usize {
113 return Err(invalid_data_len_for_ecc());
114 }
115 if msg.iter().any(|&x| x > 31) {
116 return Err(invalid_symbol());
117 }
118 Ok(())
119}
120
121impl Decoder {
122 const fn new(ecc_len: u8) -> Self {
123 if ecc_len >= 31 {
124 #[allow(unconditional_panic)]
127 ["Invalid ECC Value"][1000];
128 }
129 Decoder { ecc_len }
130 }
131
132 pub fn correct_err_count(&self,
158 msg: &[u8],
159 erase_pos: Option<&[u8]>)
160 -> Result<(Buffer, usize), CorrectionError> {
161 check_message(msg, self.ecc_len)?;
162
163 if let Some(x) = erase_pos {
164 if x.len() > self.ecc_len as usize {
165 return Err(CorrectionError::TooManyErrors);
166 }
167 if x.iter().any(|&err_pos| err_pos as usize > msg.len()) {
168 return Err(invalid_erase_pos().into());
169 }
170 }
171
172 let mut msg = Buffer::from_slice(msg, msg.len() - self.ecc_len as usize);
173
174 let erase_pos = if let Some(erase_pos) = erase_pos {
175 for e_pos in erase_pos {
176 msg[*e_pos as usize] = 0;
177 }
178 erase_pos
179 } else {
180 &[]
181 };
182
183 let synd = self.calc_syndromes(&msg);
184
185 if synd.iter().all(|x| *x == 0) {
187 return Ok((msg,0));
188 }
189
190 let fsynd = self.forney_syndromes(&synd, erase_pos, msg.len());
191 let err_loc = self.find_error_locator(&fsynd, None, erase_pos.len())?;
192 let mut err_pos = self.find_errors(&err_loc.reverse(), msg.len())?;
193
194 for x in erase_pos.iter() {
196 err_pos.push(*x);
197 }
198
199 let (msg_out, fixed) = self.correct_errata(&msg, &synd, &err_pos);
200
201 if self.is_corrupted(&msg_out)? {
203 Err(CorrectionError::TooManyErrors)
204 } else {
205 Ok((Buffer::from_polynom(msg_out, msg.len() - self.ecc_len as usize), fixed))
206 }
207 }
208
209 pub fn correct(&self,
233 msg: &[u8],
234 erase_pos: Option<&[u8]>)
235 -> Result<Buffer, CorrectionError> {
236 self.correct_err_count(msg, erase_pos).map(|(r,_)| r)
237 }
238
239 pub fn is_corrupted(&self, msg: &[u8]) -> Result<bool, UsageError> {
258 check_message(msg, self.ecc_len)?;
259 Ok((0..self.ecc_len).any(|x| msg.eval(gf::pow(2, x as i32)) != 0))
260 }
261
262 fn calc_syndromes(&self, msg: &[u8]) -> Polynom {
263 let mut synd = Polynom::with_length(self.ecc_len as usize + 1);
265 for i in 0..self.ecc_len as usize {
266 synd[i + 1] = msg.eval(gf::pow(2, i as i32))
267 }
268
269 synd
270 }
271
272 fn find_errata_locator(&self, e_pos: &[u8]) -> Polynom {
273 let mut e_loc = polynom![1];
274
275 let add_lhs = [1];
276 let mut add_rhs = [0, 0];
277 for i in e_pos.iter() {
278 add_rhs[0] = gf::pow(2, *i as i32);
279 e_loc = e_loc.mul(&add_lhs.add(&add_rhs));
280 }
281
282 e_loc
283 }
284
285 fn find_error_evaluator(&self, synd: &[u8], err_loc: &[u8], syms: usize) -> Polynom {
286 let mut divisor = Polynom::with_length(syms + 2);
287 divisor[0] = 1;
288
289 let (_, remainder) = (synd.mul(err_loc)).div(&divisor);
290 remainder
291 }
292
293 #[allow(non_snake_case)]
295 fn correct_errata(&self, msg: &[u8], synd: &[u8], err_pos: &[u8]) -> (Polynom, usize) {
296 let mut coef_pos = Polynom::with_length(err_pos.len());
298 for (i, x) in err_pos.iter().enumerate() {
299 coef_pos[i] = msg.len() as u8 - 1 - x;
300 }
301
302 let err_loc = self.find_errata_locator(&coef_pos);
303 let synd = Polynom::from(synd);
304 let err_eval = self.find_error_evaluator(&synd.reverse(), &err_loc, err_loc.len() - 1)
305 .reverse();
306
307 let mut X = Polynom::new();
308
309 for px in coef_pos.iter() {
310 let l = (31 - px) as i32;
311 X.push(gf::pow(2, -l))
312 }
313
314 let mut E = Polynom::with_length(msg.len());
315 let mut fixed = 0;
316
317 let err_eval_rev = err_eval.reverse();
318 for (i, Xi) in X.iter().enumerate() {
319 let Xi_inv = gf::inverse(*Xi);
320
321 let mut err_loc_prime_tmp = Polynom::new();
322 for (j, Xj) in X.iter().enumerate() {
323 if j != i {
324 err_loc_prime_tmp.push(gf::sub(1, gf::mul(Xi_inv, *Xj)));
325 }
326 }
327
328 let mut err_loc_prime = 1;
329 for coef in err_loc_prime_tmp.iter() {
330 err_loc_prime = gf::mul(err_loc_prime, *coef);
331 }
332
333 let y = err_eval_rev.eval(Xi_inv);
334 let y = gf::mul(gf::pow(*Xi, 1), y);
335
336 let magnitude = gf::div(y, err_loc_prime);
337
338 let E_index = err_pos[i] as usize;
339 E[E_index] = magnitude;
340 fixed += 1;
341 }
342
343 (msg.add(&E), fixed)
344 }
345
346 #[allow(non_snake_case)]
347 fn find_error_locator(&self,
348 synd: &[u8],
349 erase_loc: Option<&[u8]>,
350 erase_count: usize)
351 -> Result<Polynom, CorrectionError> {
352 let (mut err_loc, mut old_loc) = if let Some(erase_loc) = erase_loc {
353 (Polynom::from(erase_loc), Polynom::from(erase_loc))
354 } else {
355 (polynom![1], polynom![1])
356 };
357
358 let synd_shift = if synd.len() > self.ecc_len as usize {
359 synd.len() - self.ecc_len as usize
360 } else {
361 0
362 };
363
364 for i in 0..(self.ecc_len as usize - erase_count) {
365 let K = if erase_loc.is_some() {
366 erase_count + i + synd_shift
367 } else {
368 i + synd_shift
369 };
370
371 let mut delta = synd[K];
372 for j in 1..err_loc.len() {
373 let d_index = err_loc.len() - j - 1;
374 delta ^= gf::mul(err_loc[d_index], synd[K - j]);
375 }
376
377 old_loc.push(0);
378
379 if delta != 0 {
380 if old_loc.len() > err_loc.len() {
381 let new_loc = old_loc.scale(delta);
382 old_loc = err_loc.scale(gf::inverse(delta));
383 err_loc = new_loc;
384 }
385
386 err_loc = err_loc.add(&old_loc.scale(delta));
387 }
388 }
389
390 let shift = err_loc.iter().take_while(|&&v| v == 0).count();
391 let err_loc = Polynom::from(&err_loc[shift..]);
392
393 let errs = err_loc.len() - 1;
394 let errs = if erase_count > errs {
395 erase_count
396 } else {
397 (errs - erase_count) * 2 + erase_count
398 };
399
400 if errs > self.ecc_len as usize {
401 Err(CorrectionError::TooManyErrors)
402 } else {
403 Ok(err_loc)
404 }
405 }
406
407 fn find_errors(&self, err_loc: &[u8], msg_len: usize) -> Result<Polynom, CorrectionError> {
408 let errs = err_loc.len() - 1;
409 let mut err_pos = polynom![];
410
411 for i in 0..msg_len {
412 if err_loc.eval(gf::pow(2, i as i32)) == 0 {
413 let x = msg_len as u8 - 1 - i as u8;
414 err_pos.push(x);
415 }
416 }
417
418 if err_pos.len() != errs {
419 Err(CorrectionError::TooManyErrors)
420 } else {
421 Ok(err_pos)
422 }
423 }
424
425 fn forney_syndromes(&self, synd: &[u8], pos: &[u8], msg_len: usize) -> Polynom {
426 let mut erase_pos_rev = Polynom::with_length(pos.len());
427 for (i, x) in pos.iter().enumerate() {
428 erase_pos_rev[i] = msg_len as u8 - 1 - x;
429 }
430
431 let mut fsynd = Polynom::from(&synd[1..]);
432
433 for pos in erase_pos_rev.iter() {
434 let x = gf::pow(2, *pos as i32);
435 for j in 0..(fsynd.len() - 1) {
436 fsynd[j] = gf::mul(fsynd[j], x) ^ fsynd[j + 1];
437 }
438 }
439
440 fsynd
441 }
442}
443
444pub fn correct_err_count(
470 msg: &[u8],
471 ecc: u8,
472 erase_pos: Option<&[u8]>,
473) -> Result<(Buffer, usize), CorrectionError> {
474 if ecc >= 31 {
475 return Err(invalid_ecc().into());
476 }
477 Decoder::new(ecc).correct_err_count(msg, erase_pos)
478}
479
480pub fn correct(
504 msg: &[u8],
505 ecc: u8,
506 erase_pos: Option<&[u8]>,
507) -> Result<Buffer, CorrectionError> {
508 if ecc >= 31 {
509 return Err(invalid_ecc().into());
510 }
511 Decoder::new(ecc).correct(msg, erase_pos)
512}
513
514pub fn is_corrupted(msg: &[u8], ecc: u8) -> Result<bool, UsageError> {
533 if ecc >= 31 {
534 return Err(invalid_ecc().into());
535 }
536 Decoder::new(ecc).is_corrupted(msg)
537}
538
539#[cfg(test)]
540mod tests {
541 use super::*;
542 use crate::encode;
543
544 #[test]
545 fn calc_syndromes() {
546 let px = [1, 2, 3, 4, 5, 6, 7, 8, 9];
547 let mut encoded = encode(&px[..], 8).unwrap();
548
549 assert_eq!([0; 9], *Decoder::new(8).calc_syndromes(&encoded));
550
551 encoded[5] = 1;
552
553 assert_eq!([0, 7, 21, 4, 28, 30, 16, 31, 23],
554 *Decoder::new(8).calc_syndromes(&encoded));
555 }
556
557 #[test]
558 fn is_corrupted() {
559 let px = [1, 2, 3, 4, 5, 6, 7, 8, 9];
560 let mut encoded = encode(&px[..], 8).unwrap();
561
562 assert_eq!(false, Decoder::new(8).is_corrupted(&encoded).unwrap());
563
564 encoded[5] = 1;
565
566 assert_eq!(true, Decoder::new(8).is_corrupted(&encoded).unwrap());
567 }
568
569 #[test]
570 fn find_errata_locator() {
571 let e_pos = [19, 18, 17, 14, 15, 16];
572 assert_eq!([10, 11, 10, 2, 16, 15, 1],
573 *Decoder::new(6).find_errata_locator(&e_pos[..]));
574 }
575
576 #[test]
577 fn find_error_evaluator() {
578 let synd = [0, 7, 25, 13, 21, 5, 6];
579 let err_loc = [10, 11, 10, 2, 16, 15, 1];
580
581 assert_eq!([22, 13, 28, 6, 12, 2, 6],
582 *Decoder::new(6).find_error_evaluator(&synd, &err_loc, 6));
583 }
584
585 #[test]
586 fn correct_errata() {
587 let msg = [0, 0, 0, 2, 2, 2, 19, 11, 14, 18, 1, 19, 16, 3, 28, 4, 20, 12, 12];
588 let synd = [0, 11, 9, 28, 29, 14, 12, 12, 1, 10];
589 let err_pos = [0, 1, 2, 5, 4, 3];
590 let result = [10, 11, 18, 18, 11, 3, 19, 11, 14, 18, 1, 19, 16, 3, 28, 4, 20, 12, 12];
591
592 assert_eq!(result,
593 *Decoder::new(err_pos.len() as u8).correct_errata(&msg, &synd, &err_pos).0);
594 }
595
596 #[test]
597 fn error_count() {
598 let msg = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
599
600 let encoded = encode(&msg[..], 10).unwrap();
601 let mut errd = *encoded;
602
603 errd[0] = 31;
604 errd[3] = 31;
605
606 let (_correct,err) = Decoder::new(10).correct_err_count(&errd, None).unwrap();
607
608 assert_eq!(err, 2);
609 }
610
611 #[test]
612 fn find_error_locator() {
613 let synd = [29, 17, 2, 19, 4, 7, 28, 21, 6];
614 let nsym = 9;
615 let erase_loc = None;
616 let erase_count = 3;
617
618 let result = [7, 20, 30, 1];
619
620 let error_loc = Decoder::new(nsym).find_error_locator(&synd, erase_loc, erase_count);
621
622 assert!(error_loc.is_ok());
623 assert_eq!(result, *error_loc.unwrap());
624 }
625
626 #[test]
627 fn find_errors() {
628 let err_loc = [1, 24, 2, 4];
629 let msg_len = 16;
630 let result = [5, 4, 3];
631
632 let err_pos = Decoder::new(6).find_errors(&err_loc, msg_len);
633
634 assert!(err_pos.is_ok());
635 assert_eq!(result, *err_pos.unwrap());
636
637 let err_loc = [1, 2, 27, 25];
638 let msg_len = 16;
639
640 let err_pos = Decoder::new(6).find_errors(&err_loc, msg_len);
641
642 assert!(err_pos.is_err());
643 }
644
645 #[test]
646 fn forney_syndromes() {
647 let synd = [0, 29, 20, 23, 13, 24, 11];
648 let pos = [3, 4, 5];
649 let nmess = 16;
650
651 let result = [0, 0, 0, 17, 29, 11];
652 assert_eq!(result,
653 *Decoder::new(6).forney_syndromes(&synd, &pos, nmess));
654 }
655
656 #[test]
657 fn decode() {
658 let mut msg = [0, 1, 2, 31, 31, 31, 31, 31, 31, 9, 4, 1, 17, 17, 3, 9, 19, 24, 5];
659 let ecc = 9;
660 let erase_pos = [3, 4, 5];
661
662 let result = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 1, 17, 17, 3, 9, 19, 24, 5];
663
664 let decoder = Decoder::new(ecc);
665 let decoded = decoder.correct(&mut msg[..], Some(&erase_pos)).unwrap();
666
667 assert_eq!(result, **decoded);
668 }
669
670 #[test]
671 fn decode_lots_of_errors() {
672 let data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15];
675 let buffer = correct(&data, 30, None).unwrap();
676 assert_eq!(&[0u8][..], buffer.data());
677 }
678}