为什么hash()和hasher.write()的结果不一样?

为什么hash()和hasher.write()的结果不一样?,hash,rust,Hash,Rust,如果我使用hash()或hasher.write()函数,像1234这样的数字具有相同的结果,但像b“Cool”这样的字节片则没有。我觉得应该是一样的,;为什么不是呢 use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; use std::mem; fn main() { let mut hasher = DefaultHasher::new(); 1234.hash(&

如果我使用
hash()
hasher.write()
函数,像
1234这样的数字具有相同的结果,但像
b“Cool”
这样的字节片则没有。我觉得应该是一样的,;为什么不是呢

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::mem;

fn main() {
    let mut hasher = DefaultHasher::new();
    1234.hash(&mut hasher);
    println!("Hash is {:x}", hasher.finish());

    let mut hasher = DefaultHasher::new();
    hasher.write(unsafe { &mem::transmute::<i32, [u8; 4]>(1234) });
    println!("Hash is {:x}", hasher.finish());

    let mut hasher = DefaultHasher::new();
    b"Cool".hash(&mut hasher);
    println!("Hash is {:x}", hasher.finish());

    let mut hasher = DefaultHasher::new();
    hasher.write(b"Cool");
    println!("Hash is {:x}", hasher.finish());
}
正如上面所说:

所使用的默认值。没有指定内部算法,因此不应在发布时依赖它及其散列

如果我们跟随

特定实例
RandomState
将创建相同的实例,但由两个不同的
RandomState
实例创建的哈希器不太可能为相同的值生成相同的结果

:

默认情况下,
HashMap
使用选定的哈希算法来抵抗HashDoS攻击。该算法是随机种子,并尽最大努力从主机提供的高质量、安全的随机性源生成该种子,而不会阻塞程序。因此,种子的随机性取决于创建种子时系统随机数生成器的输出质量。特别是,当系统的熵池异常低时(例如在系统引导期间)生成的种子质量可能较低


我对它进行了一点深入研究,没有要求它和共享相同的行为

唯一的要求是
散列
特征。
Hasher
trait具有相同的属性,但不要求
k1->hash(k1)=Hasher(k1)

这是有意义的,因为
散列
特性是由用户实现的,用户可以随心所欲地实现它。例如,您可能希望添加到哈希中

下面是一个最小的完整且不可验证的示例,根据实现情况,该示例可能产生相同的输出或不同的输出:

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());
}

您可以确定,切片的
哈希
实现也会写入切片的长度:

#[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)
    }
}
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());
}