Created
August 27, 2021 05:06
-
-
Save AlexApps99/932809d69b7e8f1848d29e606645df4e to your computer and use it in GitHub Desktop.
A simple const CRC64 hashing implementation in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::hash::{Hash, Hasher}; | |
const CRC64_ECMA182_POLY: u64 = 0x42F0E1EBA9EA3693; | |
const CRC64_TABLE: [u64; 256] = { | |
let mut crc64table = [0u64; 256]; | |
let mut i = 0u64; | |
while i < 256 { | |
let mut crc = 0u64; | |
let mut c = i << 56; | |
let mut j = 0u8; | |
while j < 8 { | |
if ((crc ^ c) & 0x8000000000000000u64) != 0 { | |
crc = (crc << 1) ^ CRC64_ECMA182_POLY; | |
} else { | |
crc <<= 1; | |
} | |
c <<= 1; | |
j += 1; | |
} | |
crc64table[i as usize] = crc; | |
i += 1; | |
} | |
crc64table | |
}; | |
pub const fn crc64(data: &[u8], seed: u64) -> u64 { | |
let mut crc = seed; | |
let max = data.len(); | |
let mut i = 0; | |
while i < max { | |
crc = CRC64_TABLE[(((crc >> 56) as u8) ^ data[i]) as usize] ^ (crc << 8); | |
i += 1; | |
} | |
crc | |
} | |
#[derive(Copy, Clone, Debug)] | |
pub struct CRC64Hasher(pub u64); | |
impl CRC64Hasher { | |
pub const fn new(seed: u64) -> Self { | |
Self(seed) | |
} | |
} | |
impl Hasher for CRC64Hasher { | |
fn write(&mut self, bytes: &[u8]) { | |
for b in bytes { | |
self.0 = CRC64_TABLE[(((self.0 >> 56) as u8) ^ b) as usize] ^ (self.0 << 8); | |
} | |
} | |
fn finish(&self) -> u64 { | |
self.0 | |
} | |
} | |
#[test] | |
fn test_crc64() { | |
assert_eq!( | |
crc64("Testing testing 123".as_bytes(), 0), | |
0x73148096d4af1cb7 | |
); | |
assert_eq!(crc64("".as_bytes(), 0), 0); | |
assert_eq!(crc64("\u{1F602}".as_bytes(), 0), 0xa6ca62ac8ae8dce4); | |
assert_eq!(crc64(&[0xEE; 9999], 0), 0xc394f51ffa9f0ed6); | |
} | |
#[test] | |
fn test_crc64_hasher() { | |
let mut hasher = CRC64Hasher(0); | |
hasher.write("Testing testing 123".as_bytes()); | |
assert_eq!(hasher.finish(), 0x73148096d4af1cb7); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment