Skip to content

Instantly share code, notes, and snippets.

@AlexApps99
Created August 27, 2021 05:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexApps99/932809d69b7e8f1848d29e606645df4e to your computer and use it in GitHub Desktop.
Save AlexApps99/932809d69b7e8f1848d29e606645df4e to your computer and use it in GitHub Desktop.
A simple const CRC64 hashing implementation in Rust
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