4个版本
0.4.3 | 2023年3月25日 |
---|---|
0.4.2 | 2023年3月24日 |
0.4.1 | 2023年3月23日 |
0.4.0 | 2023年3月23日 |
0.3.0 |
|
#1024 in 算法
在bbolt-rs中使用
37KB
495 行
fnv-rs
Fowler–Noll–Vo哈希函数(FNV-1a)的实现,包括32、64、128、256、512和1024位变体。
关于
FNV哈希函数提供了一种更高效的Hasher
实现,适用于较小的哈希键,还有其他变体可以提供更长的哈希输出。
Rust标准库文档指出,虽然默认的Hasher
实现SipHash在许多情况下表现良好,但它明显比其他具有短键的算法慢,例如当您有一个整数到其他值的映射时。在这种情况下,FNV明显更快。
它的缺点是在较大的输入上表现不佳,并且不能提供针对碰撞攻击的保护,恶意用户可以构建特定的键来减慢哈希器的速度。因此,重要的是要对您的程序进行性能分析,以确保您正在使用小的哈希键,并且确信您的程序不会被恶意输入(包括网络服务器)所影响。
Rust编译器本身使用FNV,因为它不担心拒绝服务攻击,并且可以假设其输入将是小的——这是FNV的理想用例。
示例
如果您想使用任何较大的输出FNV变体(256、512或1024),请确保您已启用bigint
功能
[dependencies]
fnv_rs = { version = "0.4.0", features = ["bigint"] }
哈希方法
use fnv_rs::{Fnv64, FnvHasher, FnvHashResult};
let hash = Fnv64::hash(b"Hash this!testing123"); // returns FnvHashResult
println!("{}", hash); // AD2808D0C15A663E
println!("{:X}", hash); // AD2808D0C15A663E
println!("{:x}", hash); // ad2808d0c15a663e
println!("{}", hash.as_hex()); // AD2808D0C15A663E
println!("{:?}", hash.as_bytes()); // [173, 40, 8, 208, 193, 90, 102, 62]
更新方法
use fnv_rs::{Fnv64, FnvHasher, FnvHashResult};
let mut hasher = Fnv64::new();
hasher.update(b"Hash this!");
hasher.update(b"testing123");
let hash = hasher.finalize(); // returns FnvHashResult
println!("{}", hash); // AD2808D0C15A663E
在HashMap中使用FNV
FnvHashMap
类型别名是使用标准库的HashMap
与FNV的最简单方法。(这使用FNV的64位输出。)
use fnv_rs::FnvHashMap;
let mut map = FnvHashMap::default();
map.insert(1, "one");
map.insert(2, "two");
map = FnvHashMap::with_capacity_and_hasher(10, Default::default());
map.insert(1, "one");
map.insert(2, "two");
注意,标准库的HashMap::new
和HashMap::with_capacity
只实现了对RandomState
哈希器的支持,因此使用Default
来获取哈希器是下一个最佳选择。
在HashSet中使用FNV
同样地,FnvHashSet
是标准库中 HashSet
使用 FNV 的类型别名。
use fnv_rs::FnvHashSet;
let mut set = FnvHashSet::default();
set.insert(1);
set.insert(2);
set = FnvHashSet::with_capacity_and_hasher(10, Default::default());
set.insert(1);
set.insert(2);
依赖项
~195KB