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