pub(crate) fn crc8(data: &[u8]) -> u8 {
let mut crc: u8 = 0;
for &byte in data {
crc ^= byte;
for _ in 0..8 {
crc = if crc & 0x80 != 0 {
(crc << 1) ^ 0x07
} else {
crc << 1
};
}
}
crc
}
pub(crate) fn crc16(data: &[u8]) -> u16 {
let mut crc: u16 = 0;
for &byte in data {
crc ^= (byte as u16) << 8;
for _ in 0..8 {
crc = if crc & 0x8000 != 0 {
(crc << 1) ^ 0x8005
} else {
crc << 1
};
}
}
crc
}
pub(crate) fn ogg_crc32(data: &[u8]) -> u32 {
let mut crc: u32 = 0;
for &byte in data {
crc ^= (byte as u32) << 24;
for _ in 0..8 {
crc = if crc & 0x8000_0000 != 0 {
(crc << 1) ^ 0x04c1_1db7
} else {
crc << 1
};
}
}
crc
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn crc8_empty_is_zero() {
assert_eq!(crc8(&[]), 0);
}
#[test]
fn crc16_empty_is_zero() {
assert_eq!(crc16(&[]), 0);
}
#[test]
fn crc8_known_vector() {
assert_eq!(crc8(&[0x00]), 0x00);
assert_eq!(crc8(&[0x01]), 0x07);
}
#[test]
fn crc16_known_vector() {
assert_eq!(crc16(&[0x00]), 0x0000);
assert_eq!(crc16(&[0x01]), 0x8005);
}
#[test]
fn ogg_crc32_known_vectors() {
assert_eq!(ogg_crc32(b""), 0x0000_0000);
assert_eq!(ogg_crc32(b"123456789"), 0x89a1_897f);
}
}