1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! 32-bit hashing algorithms
//!
//! # Why?
//!
//! Because 32-bit architectures are a thing (e.g. ARM Cortex-M) and you don't want your hashing
//! function to pull in a bunch of slow 64-bit compiler intrinsics (software implementations of
//! 64-bit operations).
//!
//! # Relationship to `core::hash`
//!
//! This crate extends [`core::hash::Hasher`] with a 32-bit version, [`hash32::Hasher`].
//!
//! The [`hash32::Hasher`] trait requires the hasher to perform only 32-bit operations when
//! computing the hash.
//! The trait method [`hash32::Hasher::finish32`] returns the hasher's result as a `u32`.
//! The [`core::hash::Hasher::finish`] method zero-extends the [`hash32::Hasher::finish32`]
//! result to a `u64`.
//!
//! Since [`hash32::Hasher`] extends [`core::hash::Hasher`], the [`hash32::Hasher`] trait can be
//! used with any type which implements the [`core::hash::Hash`] trait.
//!
//! [`hash32::Hasher`]: crate::Hasher
//! [`hash32::Hasher::finish32`]: crate::Hasher::finish32
//! [`core::hash`]: https://doc.rust-lang.org/std/hash/index.html
//! [`finish32`]: crate::Hasher::finish32
//!
//! # Hashers
//!
//! This crate provides implementations of the following 32-bit hashing algorithms:
//!
//! - [`FnvHasher`] Fowler-Noll-Vo 1a
//! - [`Murmur3Hasher`] `MurmurHash3`
//!
//! ## Picking a hasher
//!
//! - [`FnvHasher`] is faster and consumes less code space than [`Murmur3Hasher`].
//! - [`Murmur3Hasher`] offers better collision resistance than [`FnvHasher`].
//!
//! ## Security
//!
//! Hashers provided by this crate are not cryptographically secure, and must **not** be used
//! for security purposes.
//! Additionally, unlike [`std::hash::DefaultHasher`] the provided hash algorithms lack
//! denial-of-service protection, and must only be used with trusted data.
//!
//! # Generic code
//!
//! In generic code, the trait bound `H: core::hash::Hasher` accepts **both** 64-bit hashers such
//! as [`std::hash::DefaultHasher`]; and 32-bit hashers such as the ones defined in this crate,
//! [`FnvHasher`], and [`Murmur3Hasher`].
//!
//! The trait bound `H: hash32::Hasher` is **more** restrictive as it only accepts 32-bit hashers.
//!
//! [`std::hash::DefaultHasher`]: https://doc.rust-lang.org/std/hash/struct.DefaultHasher.html
//!
//! # MSRV
//!
//! This crate is guaranteed to compile on latest stable Rust. It *might* compile on older
//! versions but that may change in any new patch release.
//!
//! # Examples
//!
//! ```
//! use hash32::{FnvHasher, Hasher as _};
//!
//! #[derive(Hash)]
//! struct Person {
//! id: u32,
//! name: &'static str,
//! phone: u64,
//! }
//!
//! let person1 = Person {
//! id: 5,
//! name: "Janet",
//! phone: 555_666_7777,
//! };
//! let person2 = Person {
//! id: 5,
//! name: "Bob",
//! phone: 555_666_7777,
//! };
//!
//! assert!(calculate_hash(&person1) != calculate_hash(&person2));
//!
//! fn calculate_hash<T: core::hash::Hash>(t: &T) -> u32 {
//! let mut fnv: FnvHasher = Default::default();
//! t.hash(&mut fnv);
//! fnv.finish32()
//! }
//! ```
pub use crateFnvHasher;
pub use crateMurmur3Hasher;
/// An extension of [`core::hash::Hasher`] for 32-bit hashers.
///
/// For hashers that implement this trait, the [`core::hash::Hasher::finish`] method should return a
/// zero-extended version of the result from [`Hasher::finish32`].
///
/// # Contract
///
/// Implementers of this trait must **not** perform any 64-bit (or 128-bit) operation while computing
/// the hash.
///
/// # Examples
///
/// ```
/// use core::hash::Hasher as _;
/// use hash32::{FnvHasher, Hasher as _};
///
/// let mut hasher: FnvHasher = Default::default();
///
/// hasher.write_u32(1989);
/// hasher.write_u8(11);
/// hasher.write_u8(9);
/// hasher.write(b"Huh?");
///
/// println!("Hash is {:x}!", hasher.finish32());
/// ```