//! * Normal 64-bit CRC calculation. //! //! Taken from Linux Kernel 6.1.9 //! //! This is a basic crc64 implementation following ECMA-182 specification, //! which can be found from, //! https://www.ecma-international.org/publications/standards/Ecma-182.htm //! //! Dr. Ross N. Williams has a great document to introduce the idea of CRC //! algorithm, here the CRC64 code is also inspired by the table-driven //! algorithm and detail example from this paper. This paper can be found //! from, //! http://www.ross.net/crc/download/crc_v3.txt //! //! crc64table[256] is the lookup table of a table-driven 64-bit CRC //! calculation, which is generated by gen_crc64table.c in kernel build //! time. The polynomial of crc64 arithmetic is from ECMA-182 specification //! as well, which is defined as, //! //! x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 + //! x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 + //! x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 + //! x^7 + x^4 + x + 1 //! //! crc64rocksoft[256] table is from the Rocksoft specification polynomial //! defined as, //! //! x^64 + x^63 + x^61 + x^59 + x^58 + x^56 + x^55 + x^52 + x^49 + x^48 + x^47 + //! x^46 + x^44 + x^41 + x^37 + x^36 + x^34 + x^32 + x^31 + x^28 + x^26 + x^23 + //! x^22 + x^19 + x^16 + x^13 + x^12 + x^10 + x^9 + x^6 + x^4 + x^3 + 1 use crate::tables::crc64::{CRC64_ROCKSOFT_TABLE, CRC64_TABLE}; /// crc64_be - Calculate bitwise big-endian ECMA-182 CRC64 /// /// ## 参数 /// /// - `crc`: seed value for computation. 0 or (u64)~0 for a new CRC calculation, /// or the previous crc64 value if computing incrementally. /// - `buf`: pointer to buffer over which CRC64 is run pub fn crc64_be(mut crc: u64, buf: &[u8]) -> u64 { for &byte in buf { let t = ((crc >> 56) ^ (byte as u64)) & 0xff; crc = CRC64_TABLE[t as usize] ^ (crc << 8); } crc } /// /// crc64_rocksoft_generic - Calculate bitwise Rocksoft CRC64 /// /// ## 参数 /// /// - `crc`: seed value for computation. 0 for a new CRC calculation, or the /// previous crc64 value if computing incrementally. /// - `buf`: pointer to buffer over which CRC64 is run pub fn crc64_rocksoft_generic(mut crc: u64, buf: &[u8]) -> u64 { crc = !crc; for &byte in buf { crc = (crc >> 8) ^ CRC64_ROCKSOFT_TABLE[(((crc & 0xff) as u8) ^ (byte)) as usize]; } return !crc; } #[cfg(test)] mod tests { use super::*; #[test] fn crc64_be_single() { let mut buf = [0u8; 1]; buf[0] = 0xaa; let crc = crc64_be(0, &buf); assert_eq!(crc, 0x2d071b6213a0cb8b); } #[test] fn crc64_be_multibytes() { let buf = b"0123456789"; let crc = crc64_be(0, buf); assert_eq!(crc, 0x2a71ab4164c3bbe8); } }