// CRC32-C (Castagnoli) checksum, used to verify broker entry metadata
// of incoming message frames.
///|
let crc32c_table : FixedArray[UInt32] = FixedArray::makei(256, fn(i) {
let mut crc = i.reinterpret_as_uint()
for _ in 0..<8 {
if (crc & 1) != 0 {
crc = (crc >> 1) ^ 0x82f63b78
} else {
crc = crc >> 1
}
}
crc
})
///|
// Advance each byte through up to eight zero bytes. Slicing-by-eight breaks
// the per-byte dependency chain without a native CPU feature or dependency.
let crc32c_slices : FixedArray[FixedArray[UInt32]] = {
let tables = FixedArray::make(8, crc32c_table)
for slice in 1..<8 {
let previous = tables[slice - 1]
tables[slice] = FixedArray::makei(256, fn(i) {
let crc = previous[i]
(crc >> 8) ^ crc32c_table[(crc & 0xff).reinterpret_as_int()]
})
}
tables
}
///|
/// Compute the CRC32-C (Castagnoli) checksum of `data`.
pub fn crc32c(data : BytesView) -> UInt32 {
let mut crc : UInt32 = 0xffffffff
let mut offset = 0
while offset <= data.length() - 8 {
let word = data[offset].to_uint() |
(data[offset + 1].to_uint() << 8) |
(data[offset + 2].to_uint() << 16) |
(data[offset + 3].to_uint() << 24)
let head = crc ^ word
crc = crc32c_slices[7][(head & 0xff).reinterpret_as_int()] ^
crc32c_slices[6][((head >> 8) & 0xff).reinterpret_as_int()] ^
crc32c_slices[5][((head >> 16) & 0xff).reinterpret_as_int()] ^
crc32c_slices[4][(head >> 24).reinterpret_as_int()] ^
crc32c_slices[3][data[offset + 4].to_int()] ^
crc32c_slices[2][data[offset + 5].to_int()] ^
crc32c_slices[1][data[offset + 6].to_int()] ^
crc32c_slices[0][data[offset + 7].to_int()]
offset += 8
}
for i in offset..> 8) ^ crc32c_table[idx]
}
crc ^ 0xffffffff
}