正如the documentation 所说:
RandomState 使用的默认 Hasher。内部算法未指定,因此不应依赖它及其哈希值。
如果我们关注RandomState...
一个特定的实例RandomState 将创建相同的Hasher 实例,但由两个不同的RandomState 实例创建的散列器不太可能为相同的值产生相同的结果。
Rationale:
默认情况下,HashMap 使用选定的哈希算法来抵抗 HashDoS 攻击。该算法是随机播种的,并尽最大努力从主机提供的高质量、安全的随机源生成此种子,而不会阻塞程序。因此,种子的随机性取决于创建种子时系统随机数生成器的输出质量。特别是,当系统的熵池异常低时(例如在系统启动期间)生成的种子可能质量较低。
我稍微研究了一下,没有要求 hash() 和 write() 具有相同的行为。
唯一的要求是 k1 == k2 -> hash(k1) == hash(k2) 对于 Hash 特征。 Hasher trait 具有相同的属性,但不要求 k1 -> hash(k1) == hasher(k1)。
这是有道理的,因为Hash trait 旨在由用户实现,他们可以随心所欲地实现它。例如,可以将salt 添加到哈希中。
这是一个最小的完整且不可验证的示例,它可以产生相同的输出或不同的输出,具体取决于实现:
use std::collections::hash_map::{DefaultHasher, RandomState};
use std::hash::{BuildHasher, Hasher, Hash};
fn main() {
let s = RandomState::new();
let mut hasher = s.build_hasher();
b"Cool".hash(&mut hasher);
println!("Hash is {:x}", hasher.finish());
let mut hasher = s.build_hasher();
hasher.write(b"Cool");
println!("Hash is {:x}", hasher.finish());
let s = DefaultHasher::new();
let mut hasher = s.clone();
b"Cool".hash(&mut hasher);
println!("Hash is {:x}", hasher.finish());
let mut hasher = s.clone();
hasher.write(b"Cool");
println!("Hash is {:x}", hasher.finish());
}
你可以see表示一个切片的Hash的实现也会写入切片的长度:
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Hash> Hash for [T] {
fn hash<H: Hasher>(&self, state: &mut H) {
self.len().hash(state);
Hash::hash_slice(self, state)
}
}
另外,hash_slice() 似乎具有您想要的行为,但并没有说明它总是如此(但我认为这是预期的行为并且不会改变,我问过here)。
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
fn main() {
let s = DefaultHasher::new();
let mut hasher = s.clone();
std::hash::Hash::hash_slice(b"Cool", &mut hasher);
println!("Hash is {:x}", hasher.finish());
let mut hasher = s.clone();
hasher.write(b"Cool");
println!("Hash is {:x}", hasher.finish());
}