pub(super) fn bytes_to_bits(bytes: &[u8]) -> Vec<u8> {
let mut bits = Vec::with_capacity(bytes.len() * 8);
for &b in bytes {
for shift in (0..8).rev() {
bits.push((b >> shift) & 1);
}
}
bits
}
pub(super) fn bits_to_base(bits: &[u8], chunk_size: u16) -> Vec<u32> {
assert!(chunk_size <= 32, "chunk_size must fit in u32");
let n = chunk_size as usize;
assert_eq!(
bits.len() % n,
0,
"bits.len() must be a multiple of chunk_size"
);
let mut result = Vec::with_capacity(bits.len() / n);
for chunk in bits.chunks(n) {
let mut acc: u32 = 0;
for &b in chunk {
acc = (acc << 1) | u32::from(b);
}
result.push(acc);
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bits_to_base_nibbles() {
assert_eq!(bits_to_base(&bytes_to_bits(&[0xA3]), 4), vec![0xA, 0x3]);
assert_eq!(
bits_to_base(&bytes_to_bits(&[0xA3, 0xF0]), 4),
vec![0xA, 0x3, 0xF, 0x0]
);
}
#[test]
fn test_bits_to_base_pairs() {
assert_eq!(bits_to_base(&bytes_to_bits(&[0xA3]), 2), vec![2, 2, 0, 3]);
}
#[test]
fn test_bits_to_base_single_bits() {
assert_eq!(
bits_to_base(&bytes_to_bits(&[0xA3]), 1),
vec![1, 0, 1, 0, 0, 0, 1, 1]
);
}
}