1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/// Generates a CRC lookup table element for a given index.
///
/// # Arguments
///
/// * `idx` - The index for which to generate the CRC lookup table element.
///
/// # Returns
///
/// A 32-bit unsigned integer representing the CRC lookup table element.
const fn get_element_from_table(idx: u32) -> u32 {
let mut r: u32 = idx << 24;
let mut i = 0;
while i < 8 {
r = (r << 1) ^ ((r >> 31) * 0x04c11db7);
i += 1;
}
r
}
/// Generates a CRC lookup table.
///
/// # Returns
///
/// An array of 256 32-bit unsigned integers representing the CRC lookup table.
const fn generate_table() -> [u32; 256] {
let mut lup_arr = [0u32; 256];
let mut i = 0;
while i < 256 {
lup_arr[i] = get_element_from_table(i as u32);
i += 1;
}
lup_arr
}
/// A constant array representing the precomputed CRC lookup table.
const CRC_LOOKUP_ARRAY: [u32; 256] = generate_table();
/// Computes the CRC-32 checksum for a slice of bytes using the Vorbis CRC-32 algorithm.
///
/// # Arguments
///
/// * `array` - A slice of bytes for which to compute the checksum.
/// * `initial` - The initial CRC value.
/// * `from` - The starting index of the slice to compute the checksum.
/// * `to` - The ending index of the slice to compute the checksum (exclusive).
///
/// # Returns
///
/// A 32-bit unsigned integer representing the CRC-32 checksum.
pub fn vorbis_crc32(array: &[u8], initial: u32, from: usize, to: usize) -> u32 {
let mut result: u32 = initial;
for i in from..to {
result = (result << 8) ^ CRC_LOOKUP_ARRAY[((array[i] as u32) ^ (result >> 24)) as usize & 0xff];
}
result
}