use crate::finite_field::ANTILOG_TABLE;
use crate::{Polynomial, ReedSolomon};
impl ReedSolomon {
#[must_use]
pub fn compute_syndromes(num_parity_bytes: u8, received: &[u8]) -> Polynomial {
let num_parity_bytes = num_parity_bytes.into();
(0..num_parity_bytes)
.map(|i| Polynomial::eval_coefficients_at(received, ANTILOG_TABLE[i + 1].get()))
.collect()
}
}
#[cfg(test)]
mod tests {
use ps_buffer::ToBuffer;
use crate::ReedSolomon;
type TestError = Box<dyn std::error::Error>;
#[test]
fn test_compute_syndromes_no_errors() -> Result<(), TestError> {
let rs = ReedSolomon::new(2)?;
let message = b"Syndrome".to_buffer()?;
let encoded = rs.encode(&message)?;
let syndromes = ReedSolomon::compute_syndromes(rs.parity_bytes(), &encoded);
assert!(syndromes.is_zero());
Ok(())
}
#[test]
fn test_compute_syndromes_with_errors() -> Result<(), TestError> {
let rs = ReedSolomon::new(2)?;
let message = b"Syndrome".to_buffer()?;
let encoded = rs.encode(&message)?;
let mut corrupted = encoded.clone()?;
corrupted[0] ^= 1;
let syndromes = ReedSolomon::compute_syndromes(rs.parity_bytes(), &corrupted);
assert!(syndromes.iter().any(|&s| s != 0));
Ok(())
}
#[test]
fn test_compute_syndromes_empty_codeword() {
let syndromes = ReedSolomon::compute_syndromes(4u8, &[]);
assert_eq!(syndromes.degree(), 0);
assert!(syndromes.is_zero());
}
#[test]
fn test_single_error_syndrome_length() -> Result<(), TestError> {
let rs = ReedSolomon::new(3)?;
let message = b"Hello".to_buffer()?;
let encoded = rs.encode(&message)?;
let parity_bytes: usize = rs.parity_bytes().into();
let mut corrupted = encoded.clone()?;
corrupted[0] ^= 1;
let syndromes = ReedSolomon::compute_syndromes(rs.parity_bytes(), &corrupted);
let full = syndromes.first_n_coefficients(parity_bytes);
assert_eq!(full.len(), parity_bytes);
let trimmed = syndromes.coefficients();
assert_eq!(
trimmed.len(),
parity_bytes,
"coefficients() returned {} elements, expected {}",
trimmed.len(),
parity_bytes
);
Ok(())
}
}