static INITIAL_CRC: u32 = 0;
pub const SIZE: usize = 4;
#[cfg(test)]
fn extend_slow(initial_crc: u32, data: &[u8]) -> u32 {
let mut reg = !initial_crc;
for &byte in data.iter() {
reg ^= byte as u32;
for _ in 0..8 {
reg = if reg & 0x00000001 != 0 {
(reg >> 1) ^ 0x9960034C
} else {
reg >> 1
};
}
}
return !reg;
}
static PARTIAL_RESULTS: [u32; 256] = [
0x548843E7, 0x9AD08156, 0xFAF9C01C, 0x34A102AD, 0x3AAB4288, 0xF4F38039, 0x94DAC173, 0x5A8203C2,
0x88CE4139, 0x46968388, 0x26BFC2C2, 0xE8E70073, 0xE6ED4056, 0x28B582E7, 0x489CC3AD, 0x86C4011C,
0xDEC440C2, 0x109C8273, 0x70B5C339, 0xBEED0188, 0xB0E741AD, 0x7EBF831C, 0x1E96C256, 0xD0CE00E7,
0x0282421C, 0xCCDA80AD, 0xACF3C1E7, 0x62AB0356, 0x6CA14373, 0xA2F981C2, 0xC2D0C088, 0x0C880239,
0x72D04334, 0xBC888185, 0xDCA1C0CF, 0x12F9027E, 0x1CF3425B, 0xD2AB80EA, 0xB282C1A0, 0x7CDA0311,
0xAE9641EA, 0x60CE835B, 0x00E7C211, 0xCEBF00A0, 0xC0B54085, 0x0EED8234, 0x6EC4C37E, 0xA09C01CF,
0xF89C4011, 0x36C482A0, 0x56EDC3EA, 0x98B5015B, 0x96BF417E, 0x58E783CF, 0x38CEC285, 0xF6960034,
0x24DA42CF, 0xEA82807E, 0x8AABC134, 0x44F30385, 0x4AF943A0, 0x84A18111, 0xE488C05B, 0x2AD002EA,
0x18384241, 0xD66080F0, 0xB649C1BA, 0x7811030B, 0x761B432E, 0xB843819F, 0xD86AC0D5, 0x16320264,
0xC47E409F, 0x0A26822E, 0x6A0FC364, 0xA45701D5, 0xAA5D41F0, 0x64058341, 0x042CC20B, 0xCA7400BA,
0x92744164, 0x5C2C83D5, 0x3C05C29F, 0xF25D002E, 0xFC57400B, 0x320F82BA, 0x5226C3F0, 0x9C7E0141,
0x4E3243BA, 0x806A810B, 0xE043C041, 0x2E1B02F0, 0x201142D5, 0xEE498064, 0x8E60C12E, 0x4038039F,
0x3E604292, 0xF0388023, 0x9011C169, 0x5E4903D8, 0x504343FD, 0x9E1B814C, 0xFE32C006, 0x306A02B7,
0xE226404C, 0x2C7E82FD, 0x4C57C3B7, 0x820F0106, 0x8C054123, 0x425D8392, 0x2274C2D8, 0xEC2C0069,
0xB42C41B7, 0x7A748306, 0x1A5DC24C, 0xD40500FD, 0xDA0F40D8, 0x14578269, 0x747EC323, 0xBA260192,
0x686A4369, 0xA63281D8, 0xC61BC092, 0x08430223, 0x06494206, 0xC81180B7, 0xA838C1FD, 0x6660034C,
0xCDE840AB, 0x03B0821A, 0x6399C350, 0xADC101E1, 0xA3CB41C4, 0x6D938375, 0x0DBAC23F, 0xC3E2008E,
0x11AE4275, 0xDFF680C4, 0xBFDFC18E, 0x7187033F, 0x7F8D431A, 0xB1D581AB, 0xD1FCC0E1, 0x1FA40250,
0x47A4438E, 0x89FC813F, 0xE9D5C075, 0x278D02C4, 0x298742E1, 0xE7DF8050, 0x87F6C11A, 0x49AE03AB,
0x9BE24150, 0x55BA83E1, 0x3593C2AB, 0xFBCB001A, 0xF5C1403F, 0x3B99828E, 0x5BB0C3C4, 0x95E80175,
0xEBB04078, 0x25E882C9, 0x45C1C383, 0x8B990132, 0x85934117, 0x4BCB83A6, 0x2BE2C2EC, 0xE5BA005D,
0x37F642A6, 0xF9AE8017, 0x9987C15D, 0x57DF03EC, 0x59D543C9, 0x978D8178, 0xF7A4C032, 0x39FC0283,
0x61FC435D, 0xAFA481EC, 0xCF8DC0A6, 0x01D50217, 0x0FDF4232, 0xC1878083, 0xA1AEC1C9, 0x6FF60378,
0xBDBA4183, 0x73E28332, 0x13CBC278, 0xDD9300C9, 0xD39940EC, 0x1DC1825D, 0x7DE8C317, 0xB3B001A6,
0x8158410D, 0x4F0083BC, 0x2F29C2F6, 0xE1710047, 0xEF7B4062, 0x212382D3, 0x410AC399, 0x8F520128,
0x5D1E43D3, 0x93468162, 0xF36FC028, 0x3D370299, 0x333D42BC, 0xFD65800D, 0x9D4CC147, 0x531403F6,
0x0B144228, 0xC54C8099, 0xA565C1D3, 0x6B3D0362, 0x65374347, 0xAB6F81F6, 0xCB46C0BC, 0x051E020D,
0xD75240F6, 0x190A8247, 0x7923C30D, 0xB77B01BC, 0xB9714199, 0x77298328, 0x1700C262, 0xD95800D3,
0xA70041DE, 0x6958836F, 0x0971C225, 0xC7290094, 0xC92340B1, 0x077B8200, 0x6752C34A, 0xA90A01FB,
0x7B464300, 0xB51E81B1, 0xD537C0FB, 0x1B6F024A, 0x1565426F, 0xDB3D80DE, 0xBB14C194, 0x754C0325,
0x2D4C42FB, 0xE314804A, 0x833DC100, 0x4D6503B1, 0x436F4394, 0x8D378125, 0xED1EC06F, 0x234602DE,
0xF10A4025, 0x3F528294, 0x5F7BC3DE, 0x9123016F, 0x9F29414A, 0x517183FB, 0x3158C2B1, 0xFF000000,
];
pub fn extend(initial_crc: u32, data: &[u8]) -> u32 {
let mut crc = initial_crc;
for &byte in data.iter() {
crc = (crc >> 8) ^ PARTIAL_RESULTS[(crc as u8 ^ byte) as usize];
}
crc
}
pub fn compute(data: &[u8]) -> u32 {
extend(INITIAL_CRC, data)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn zero_nonzero_crc() {
assert!(extend_slow(0, &[0]) != 0);
}
#[test]
fn basic() {
assert_eq!(extend_slow(0, "123456789".as_bytes().into()), 0x11A6F2A3);
assert_eq!(extend(0, "123456789".as_bytes().into()), 0x11A6F2A3);
}
#[test]
fn random() {
for _ in 0..100 {
let data = (0..1024)
.map(|_| rand::random::<u8>())
.collect::<Vec<_>>()
.into_boxed_slice();
let initial_crc = rand::random::<u32>();
assert_eq!(extend_slow(initial_crc, &data), extend(initial_crc, &data));
}
}
}