crczoo 0.1.3

CRC Zoo: A collection of Cyclic Redundancy Check (CRC) algorithms
Documentation
pub fn calculate_crc32(data: &[u8], poly: u32, init: u32, ref_in: bool, ref_out: bool, xor_out: u32) -> u32 {
    let mut crc = init;
    for d in data.iter() {
        let c = if ref_in { (*d).reverse_bits() } else { *d };
        let mut i = 0x80;
        while i > 0 {
            let mut bit = (crc & 0x80000000) != 0;
            if (c & i) != 0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i >>= 1;
        }
    }
    if ref_out {
        crc = crc.reverse_bits();
    }
    crc ^ xor_out
}

pub const CRC32_POLY: u32 = 0x04C11DB7;
pub fn crc32(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32_POLY, 0xFFFFFFFF, true, true, 0xFFFFFFFF)
}

pub const CRC32_BZIP2_POLY: u32 = 0x04C11DB7;
pub fn crc32_bzip2(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32_BZIP2_POLY, 0xFFFFFFFF, false, false, 0xFFFFFFFF)
}

pub const CRC32C_POLY: u32 = 0x1EDC6F41;
pub fn crc32c(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32C_POLY, 0xFFFFFFFF, true, true, 0xFFFFFFFF)
}

pub const CRC32D_POLY: u32 = 0xA833982B;
pub fn crc32d(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32D_POLY, 0xFFFFFFFF, true, true, 0xFFFFFFFF)
}

pub const CRC32_MPEG2_POLY: u32 = 0x04C11DB7;
pub fn crc32_mpeg2(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32_MPEG2_POLY, 0xFFFFFFFF, false, false, 0x00000000)
}

pub const CRC32_POSIX_POLY: u32 = 0x04C11DB7;
pub fn crc32_posix(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32_POSIX_POLY, 0x00000000, false, false, 0xFFFFFFFF)
}

pub const CRC32Q_POLY: u32 = 0x814141AB;
pub fn crc32q(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32Q_POLY, 0x00000000, false, false, 0x00000000)
}

pub const CRC32_JAMCRC_POLY: u32 = 0x04C11DB7;
pub fn crc32_jamcrc(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32_JAMCRC_POLY, 0xFFFFFFFF, true, true, 0x00000000)
}

pub const CRC32_XFER_POLY: u32 = 0x000000AF;
pub fn crc32_xfer(data: &[u8]) -> u32 {
    calculate_crc32(data, CRC32_XFER_POLY, 0x00000000, false, false, 0x00000000)
}

#[cfg(test)]
mod tests {
    use super::*;

    fn check_sequence() -> Vec<u8> {
        "123456789".to_owned().into_bytes()
    }

    fn check_sequence_long() -> Vec<u8> {
        "helloworldchris!".to_owned().into_bytes()
    }

    #[test]
    fn test_crc32() {
        assert_eq!(crc32(&check_sequence()), 0xCBF43926);
    }

    #[test]
    fn test_crc32_long() {
        assert_eq!(crc32(&check_sequence_long()), 0x8783E15A);
    }

    #[test]
    fn test_crc32_long_long() {
        let mut data = check_sequence_long();
        data.append(&mut check_sequence_long());
        assert_eq!(crc32(&data), 0x2C2014D4);
    }

    #[test]
    fn test_crc32_long_long_long() {
        let mut data = check_sequence_long();
        data.append(&mut check_sequence_long());
        data.append(&mut check_sequence_long());
        assert_eq!(crc32(&data), 0xEDA8F8B7);
    }

    #[test]
    fn test_crc32_bzip2() {
        assert_eq!(crc32_bzip2(&check_sequence()), 0xFC891918);
    }

    #[test]
    fn test_crc32c() {
        assert_eq!(crc32c(&check_sequence()), 0xE3069283);
    }

    #[test]
    fn test_crc32d() {
        assert_eq!(crc32d(&check_sequence()), 0x87315576);
    }

    #[test]
    fn test_crc32_mpeg2() {
        assert_eq!(crc32_mpeg2(&check_sequence()), 0x0376E6E7);
    }

    #[test]
    fn test_crc32_mpeg2_long() {
        assert_eq!(crc32_mpeg2(&check_sequence_long()), 0xD13D2899);
    }

    #[test]
    fn test_crc32_posix() {
        assert_eq!(crc32_posix(&check_sequence()), 0x765E7680);
    }

    #[test]
    fn test_crc32q() {
        assert_eq!(crc32q(&check_sequence()), 0x3010BF7F);
    }

    #[test]
    fn test_crc32_jamcrc() {
        assert_eq!(crc32_jamcrc(&check_sequence()), 0x340BC6D9);
    }

    #[test]
    fn test_crc32_xfer() {
        assert_eq!(crc32_xfer(&check_sequence()), 0xBD0BE338);
    }
}