pub(super) struct Gf {
logt: Vec<u8>,
alog: Vec<u8>,
}
impl Gf {
pub(super) fn new(poly: u16, m: u32) -> Gf {
let size = 1usize << m;
let mut logt = vec![0u8; size];
let mut alog = vec![0u8; size * 2];
let mut x = 1u16;
for (i, slot) in alog.iter_mut().take(size - 1).enumerate() {
*slot = x as u8;
logt[x as usize] = i as u8;
x <<= 1;
if x & size as u16 != 0 {
x ^= poly;
}
}
for i in (size - 1)..(size * 2) {
alog[i] = alog[i - (size - 1)];
}
Gf { logt, alog }
}
}
pub(super) struct RsEncoder<'a> {
gf: &'a Gf,
rspoly: Vec<u8>,
log_rspoly: Vec<usize>,
nsym: usize,
}
impl<'a> RsEncoder<'a> {
pub(super) fn new(gf: &'a Gf, nsym: usize, index: i32) -> RsEncoder<'a> {
let mut rspoly = vec![0u8; nsym + 1];
rspoly[0] = 1;
for i in 1..=nsym {
let idx = index as usize + (i - 1);
rspoly[i] = 1;
for k in (1..i).rev() {
if rspoly[k] != 0 {
rspoly[k] = gf.alog[gf.logt[rspoly[k] as usize] as usize + idx];
}
rspoly[k] ^= rspoly[k - 1];
}
rspoly[0] = gf.alog[gf.logt[rspoly[0] as usize] as usize + idx];
}
let log_rspoly = rspoly
.iter()
.map(|&c| gf.logt[c as usize] as usize)
.collect();
RsEncoder {
gf,
rspoly,
log_rspoly,
nsym,
}
}
pub(super) fn encode(&self, data: &[u8]) -> Vec<u8> {
let nsym = self.nsym;
let mut res = vec![0u8; nsym];
for &d in data {
let m = res[nsym - 1] ^ d;
if m != 0 {
let log_m = self.gf.logt[m as usize] as usize;
for k in (1..nsym).rev() {
res[k] = if self.rspoly[k] != 0 {
res[k - 1] ^ self.gf.alog[log_m + self.log_rspoly[k]]
} else {
res[k - 1]
};
}
res[0] = self.gf.alog[log_m + self.log_rspoly[0]];
} else {
for k in (1..nsym).rev() {
res[k] = res[k - 1];
}
res[0] = 0;
}
}
res.reverse();
res
}
}