Seahash can't hash buffers byte-wise
Created by: asomers
SeaHash does not produce the same result when hashing a whole buffer as when hashing its constituent parts. For example, calling SeaHasher::write
on the whole buffer provides a different result than calling SeaHasher::write
on subslices, or calling SeaHasher::write_u8
on each byte. Rust's DefaultHasher
as well as MetroHash64
and MetroHash128
do have this property. I haven't tested any others. This test case demonstrates the problem. Just replace the type MyHasher
line to test different Hasher
implementations:
#[test]
fn test_hash_slice() {
use metrohash::{MetroHash64, MetroHash128};
use seahash::SeaHasher;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
type MyHasher = DefaultHasher;
let sl: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7];
let mut slice_hasher = MyHasher::new();
let mut halfslice_hasher = MyHasher::new();
let mut u8_hasher = MyHasher::new();
let mut u16_hasher = MyHasher::new();
let mut u32_hasher = MyHasher::new();
let mut u64_hasher = MyHasher::new();
slice_hasher.write(&sl[..]);
halfslice_hasher.write(&sl[0..4]);
halfslice_hasher.write(&sl[4..8]);
u8_hasher.write_u8(0);
u8_hasher.write_u8(1);
u8_hasher.write_u8(2);
u8_hasher.write_u8(3);
u8_hasher.write_u8(4);
u8_hasher.write_u8(5);
u8_hasher.write_u8(6);
u8_hasher.write_u8(7);
u16_hasher.write_u16(u16::from_be(0x0001));
u16_hasher.write_u16(u16::from_be(0x0203));
u16_hasher.write_u16(u16::from_be(0x0405));
u16_hasher.write_u16(u16::from_be(0x0607));
u32_hasher.write_u32(u32::from_be(0x00010203));
u32_hasher.write_u32(u32::from_be(0x04050607));
u64_hasher.write_u64(u64::from_be(0x0001020304050607));
let slice_hash = slice_hasher.finish();
assert_eq!(slice_hash, halfslice_hasher.finish());
assert_eq!(slice_hash, u64_hasher.finish());
assert_eq!(slice_hash, u32_hasher.finish());
assert_eq!(slice_hash, u16_hasher.finish());
assert_eq!(slice_hash, u8_hasher.finish());
}