Trait Hasher
trait Hasher
A trait for hashing an arbitrary stream of bytes.
Instances of Hasher usually represent state that is changed while hashing
data.
Hasher provides a fairly basic interface for retrieving the generated hash
(with finish), and writing integers as well as slices of bytes into an
instance (with write and write_u8 etc.). Most of the time, Hasher
instances are used in conjunction with the Hash trait.
This trait provides no guarantees about how the various write_* methods are
defined and implementations of Hash should not assume that they work one
way or another. You cannot assume, for example, that a write_u32 call is
equivalent to four calls of write_u8. Nor can you assume that adjacent
write calls are merged, so it's possible, for example, that
#
and
#
end up producing different hashes.
Thus to produce the same hash value, Hash implementations must ensure
for equivalent items that exactly the same sequence of calls is made -- the
same methods with the same parameters in the same order.
Examples
use ;
let mut hasher = new;
hasher.write_u32;
hasher.write_u8;
hasher.write_u8;
hasher.write;
println!;
Required Methods
fn finish(self: &Self) -> u64Returns the hash value for the values written so far.
Despite its name, the method does not reset the hasher’s internal state. Additional
writes will continue from the current value. If you need to start a fresh hash value, you will have to create a new hasher.Examples
use ; let mut hasher = new; hasher.write; println!;fn write(self: &mut Self, bytes: &[u8])Writes some data into this
Hasher.Examples
use ; let mut hasher = new; let data = ; hasher.write; println!;Note to Implementers
You generally should not do length-prefixing as part of implementing this method. It's up to the
Hashimplementation to callHasher::write_length_prefixbefore sequences that need it.
Provided Methods
fn write_u8(self: &mut Self, i: u8)Writes a single
u8into this hasher.fn write_u16(self: &mut Self, i: u16)Writes a single
u16into this hasher.fn write_u32(self: &mut Self, i: u32)Writes a single
u32into this hasher.fn write_u64(self: &mut Self, i: u64)Writes a single
u64into this hasher.fn write_u128(self: &mut Self, i: u128)Writes a single
u128into this hasher.fn write_usize(self: &mut Self, i: usize)Writes a single
usizeinto this hasher.fn write_i8(self: &mut Self, i: i8)Writes a single
i8into this hasher.fn write_i16(self: &mut Self, i: i16)Writes a single
i16into this hasher.fn write_i32(self: &mut Self, i: i32)Writes a single
i32into this hasher.fn write_i64(self: &mut Self, i: i64)Writes a single
i64into this hasher.fn write_i128(self: &mut Self, i: i128)Writes a single
i128into this hasher.fn write_isize(self: &mut Self, i: isize)Writes a single
isizeinto this hasher.fn write_length_prefix(self: &mut Self, len: usize)Writes a length prefix into this hasher, as part of being prefix-free.
If you're implementing
Hashfor a custom collection, call this before writing its contents to thisHasher. That way(collection![1, 2, 3], collection![4, 5])and(collection![1, 2], collection![3, 4, 5])will provide different sequences of values to theHasherThe
impl<T> Hash for [T]includes a call to this method, so if you're hashing a slice (or array or vector) via itsHash::hashmethod, you should not call this yourself.This method is only for providing domain separation. If you want to hash a
usizethat represents part of the data, then it's important that you pass it toHasher::write_usizeinstead of to this method.Examples
# // Stubs to make the `impl` below pass the compiler # # ; # # use ;Note to Implementers
If you've decided that your
Hasheris willing to be susceptible to Hash-DoS attacks, then you might consider skipping hashing some or all of thelenprovided in the name of increased performance.fn write_str(self: &mut Self, s: &str)Writes a single
strinto this hasher.If you're implementing
Hash, you generally do not need to call this, as theimpl Hash for strdoes, so you should prefer that instead.This includes the domain separator for prefix-freedom, so you should not call
Self::write_length_prefixbefore calling this.Note to Implementers
There are at least two reasonable default ways to implement this. Which one will be the default is not yet decided, so for now you probably want to override it specifically.
The general answer
It's always correct to implement this with a length prefix:
# # ; #And, if your
Hasherworks inusizechunks, this is likely a very efficient way to do it, as anything more complicated may well end up slower than just running the round with the length.If your
Hasherworks byte-wiseOne nice thing about
strbeing UTF-8 is that theb'\xFF'byte never happens. That means that you can append that to the byte stream being hashed and maintain prefix-freedom:# # ; #This does require that your implementation not add extra padding, and thus generally requires that you maintain a buffer, running a round only once that buffer is full (or
finishis called).That's because if
writepads data out to a fixed chunk size, it's likely that it does it in such a way that"a"and"a\x00"would end up hashing the same sequence of things, introducing conflicts.
Implementors
impl<H: Hasher + ?Sized> Hasher for &mut Himpl Hasher for SipHasher