#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct Fingerprint(u64);
impl Fingerprint {
#[must_use]
pub const fn get(self) -> u64 {
self.0
}
}
impl Fingerprint {
pub(crate) fn of(parts: &[&[u8]]) -> Self {
let mut hasher = Fnv1a::new();
for (i, part) in parts.iter().enumerate() {
if i > 0 {
hasher.write(&[0]);
}
hasher.write(part);
}
Self(hasher.finish())
}
}
struct Fnv1a(u64);
impl Fnv1a {
const OFFSET: u64 = 0xcbf2_9ce4_8422_2325;
const PRIME: u64 = 0x0000_0100_0000_01b3;
const fn new() -> Self {
Self(Self::OFFSET)
}
fn write(&mut self, bytes: &[u8]) {
for byte in bytes {
self.0 = (self.0 ^ u64::from(*byte)).wrapping_mul(Self::PRIME);
}
}
const fn finish(&self) -> u64 {
self.0
}
}