Skip to content

Instantly share code, notes, and snippets.

@NoraCodes
Created January 10, 2022 21:26
Show Gist options
  • Save NoraCodes/d2f553e3f34fdae4f4d275649c092122 to your computer and use it in GitHub Desktop.
Save NoraCodes/d2f553e3f34fdae4f4d275649c092122 to your computer and use it in GitHub Desktop.
SeaHash investigation - why is Fasthash's implementation weird?
use fasthash; // 0.4
use seahash; // 4
use std::hash::Hasher;
// FastHash seeds
const SEAHASH_SK0: u64 = 0xe7b0c93ca8525013;
const SEAHASH_SK1: u64 = 0x011d02b854ae8182;
const SEAHASH_SK2: u64 = 0x7bcc5cf9c39cec76;
const SEAHASH_SK3: u64 = 0xfa336285d102d083;
struct FastSeaHash {
inner: fasthash::SeaHasher
}
struct CanonicalSeaHash {
inner: seahash::SeaHasher
}
impl Default for FastSeaHash {
fn default() -> Self {
Self {
inner: fasthash::SeaHasher::with_seeds(
SEAHASH_SK0,
SEAHASH_SK1,
SEAHASH_SK2,
SEAHASH_SK3
)
}
}
}
impl Hasher for FastSeaHash {
fn write(&mut self, bytes: &[u8]) {
self.inner.write(bytes);
}
fn finish(&self) -> u64 {
self.inner.finish()
}
fn write_u64(&mut self, n: u64) {
self.inner.write_u64(n)
}
fn write_u8(&mut self, n: u8) {
self.inner.write_u8(n)
}
fn write_u16(&mut self, n: u16) {
self.inner.write_u16(n)
}
fn write_u32(&mut self, n: u32) {
self.inner.write_u32(n)
}
fn write_usize(&mut self, n: usize) {
self.inner.write_usize(n)
}
fn write_i64(&mut self, n: i64) {
self.inner.write_i64(n)
}
fn write_i8(&mut self, n: i8) {
self.inner.write_i8(n)
}
fn write_i16(&mut self, n: i16) {
self.inner.write_i16(n)
}
fn write_i32(&mut self, n: i32) {
self.inner.write_i32(n)
}
fn write_isize(&mut self, n: isize) {
self.inner.write_isize(n)
}
}
impl Default for CanonicalSeaHash {
fn default() -> Self {
Self {
inner: seahash::SeaHasher::with_seeds(
SEAHASH_SK0,
SEAHASH_SK1,
SEAHASH_SK2,
SEAHASH_SK3
)
}
}
}
impl Hasher for CanonicalSeaHash {
fn write(&mut self, bytes: &[u8]) {
self.inner.write(bytes);
}
fn finish(&self) -> u64 {
self.inner.finish()
}
fn write_u64(&mut self, n: u64) {
self.inner.write_u64(n)
}
fn write_u8(&mut self, n: u8) {
self.inner.write_u8(n)
}
fn write_u16(&mut self, n: u16) {
self.inner.write_u16(n)
}
fn write_u32(&mut self, n: u32) {
self.inner.write_u32(n)
}
fn write_usize(&mut self, n: usize) {
self.inner.write_usize(n)
}
fn write_i64(&mut self, n: i64) {
self.inner.write_i64(n)
}
fn write_i8(&mut self, n: i8) {
self.inner.write_i8(n)
}
fn write_i16(&mut self, n: i16) {
self.inner.write_i16(n)
}
fn write_i32(&mut self, n: i32) {
self.inner.write_i32(n)
}
fn write_isize(&mut self, n: isize) {
self.inner.write_isize(n)
}
}
#[test]
fn test_hashes_consistent() {
let mut fasthash = FastSeaHash::default();
let mut seahash = CanonicalSeaHash::default();
fasthash.write_u64(0xdeadbeef_u64);
seahash.write_u64(0xdeadbeef_u64);
assert_eq!(fasthash.finish(), seahash.finish()); // Fails
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment