From c6c80c906c0ec7d36f7bca3808b615c6113891f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Tue, 16 Jun 2026 23:40:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Reed-Solomon=20=E7=BA=A0=E9=94=99?= =?UTF-8?q?=E7=BC=96=E7=A0=81=20+=20=E6=95=B0=E6=8D=AE=E4=BA=A4=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/ecc/reed_solomon.rs | 145 ++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/core/src/ecc/reed_solomon.rs b/core/src/ecc/reed_solomon.rs index 928e124..0d6c4a2 100644 --- a/core/src/ecc/reed_solomon.rs +++ b/core/src/ecc/reed_solomon.rs @@ -1 +1,144 @@ -// FIXME: Reed-Solomon 编码器 — Task 4 +use crate::ecc::galois; + +/// 计算多项式相乘: a(x) * b(x) in GF(2⁸) +fn poly_mul(a: &[u8], b: &[u8]) -> Vec { + let mut result = vec![0u8; a.len() + b.len() - 1]; + for (i, &ai) in a.iter().enumerate() { + for (j, &bj) in b.iter().enumerate() { + result[i + j] = galois::add(result[i + j], galois::mul(ai, bj)); + } + } + result +} + +/// 构造 RS 生成多项式: ∏ᵢ₌₀ⁿ⁻¹ (x - αⁱ) +/// 参数 n: 纠错码字数 +fn generator_polynomial(n: u8) -> Vec { + let mut g = vec![1u8]; // 从 g(x) = 1 开始 + for i in 0..n { + // g(x) *= (x + αⁱ) in GF(2⁸) — 注意加法和减法相同 + let factor = vec![1u8, galois::pow(2, i as usize)]; + g = poly_mul(&g, &factor); + } + g +} + +/// 多项式长除法: message(x) * xⁿ ÷ generator(x),返回余数(即纠错码字) +/// data: 数据码字 +/// ec_count: 纠错码字数量 +pub fn compute_ec(data: &[u8], ec_count: u8) -> Vec { + let gen = generator_polynomial(ec_count); + // 构造被除数: data 后接 ec_count 个零 + let mut dividend = vec![0u8; data.len() + ec_count as usize]; + dividend[..data.len()].copy_from_slice(data); + + // 多项式长除法 + for i in 0..data.len() { + let coef = dividend[i]; + if coef != 0 { + for (j, &g) in gen.iter().enumerate() { + dividend[i + j] = galois::add(dividend[i + j], galois::mul(coef, g)); + } + } + } + + // 余数 = 最后 ec_count 个系数 + dividend[data.len()..].to_vec() +} + +/// 对一组数据块生成纠错码字并交错排列 +/// blocks: 每个数据块的内容 +/// ec_count: 每块纠错码字数 +/// 返回: 数据码字交错 + 纠错码字交错 +pub fn interleave(blocks: &[Vec], ec_count: u8) -> Vec { + // 数据码字交错:取每块第1个,再取每块第2个... + let max_data = blocks.iter().map(|b| b.len()).max().unwrap_or(0); + let mut result = Vec::new(); + + for i in 0..max_data { + for block in blocks.iter() { + if i < block.len() { + result.push(block[i]); + } + } + } + + // 对每个块计算 EC + let ec_blocks: Vec> = blocks + .iter() + .map(|b| compute_ec(b, ec_count)) + .collect(); + + // EC 码字交错 + for i in 0..ec_count as usize { + for ec in ec_blocks.iter() { + result.push(ec[i]); + } + } + + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_generator_polynomial_degree() { + let g = generator_polynomial(7); + // 7 个纠错码字 → 生成多项式应为 7 次,共 8 个系数 + assert_eq!(g.len(), 8); + // 首项系数应为 1 (x⁷ 的系数) + assert_eq!(g[0], 1); + } + + #[test] + fn test_compute_ec_zero_data() { + // 全零数据 + EC → EC 应全零 + let ec = compute_ec(&vec![0u8; 19], 7); + assert_eq!(ec, vec![0u8; 7]); + } + + #[test] + fn test_compute_ec_length() { + let data = vec![ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + ]; + let ec = compute_ec(&data, 10); + // EC 码字数量应等于 ec_count + assert_eq!(ec.len(), 10); + } + + #[test] + fn test_compute_ec_nonzero() { + // 非零数据应产生非零 EC + let data = vec![ + 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, + 0xEC, 0x11, 0xA3, 0x12, 0xD3, + ]; + let ec = compute_ec(&data, 7); + assert_eq!(ec.len(), 7); + // 非零数据 + 非零多项式 → EC 不应全零 + assert!(ec.iter().any(|&x| x != 0)); + } + + #[test] + fn test_interleave_basic() { + let b1 = vec![1, 2, 3]; + let b2 = vec![4, 5]; + // 数据交错: 1, 4, 2, 5, 3 + // EC 交错: b1_ec[0], b2_ec[0], b1_ec[1], b2_ec[1], ... + let result = interleave(&[b1, b2], 2); + // 前 5 个是数据交错 + assert_eq!(&result[..5], &[1, 4, 2, 5, 3]); + } + + #[test] + fn test_interleave_single_block() { + let b1 = vec![10, 20, 30]; + let result = interleave(&[b1.clone()], 3); + // 单个块: 数据直接输出 + 3 个 EC + assert_eq!(&result[..3], &[10, 20, 30]); + assert_eq!(result.len(), 6); // 3 data + 3 ec + } +}