]> git.lizzy.rs Git - rust.git/blob - src/libstd/hash.rs
e4017ea5a47fa8338299f99a5d628d8cf92cd944
[rust.git] / src / libstd / hash.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12  * Generic hashing support.
13  *
14  * This module provides a generic way to compute the hash of a value. The
15  * simplest way to make a type hashable is to use `#[deriving(Hash)]`:
16  *
17  * # Example
18  *
19  * ```rust
20  * use std::hash;
21  * use std::hash::Hash;
22  *
23  * #[deriving(Hash)]
24  * struct Person {
25  *     id: uint,
26  *     name: String,
27  *     phone: u64,
28  * }
29  *
30  * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
31  * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
32  *
33  * assert!(hash::hash(&person1) != hash::hash(&person2));
34  * ```
35  *
36  * If you need more control over how a value is hashed, you need to implement
37  * the trait `Hash`:
38  *
39  * ```rust
40  * use std::hash;
41  * use std::hash::Hash;
42  * use std::hash::sip::SipState;
43  *
44  * struct Person {
45  *     id: uint,
46  *     name: String,
47  *     phone: u64,
48  * }
49  *
50  * impl Hash for Person {
51  *     fn hash(&self, state: &mut SipState) {
52  *         self.id.hash(state);
53  *         self.phone.hash(state);
54  *     }
55  * }
56  *
57  * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
58  * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
59  *
60  * assert!(hash::hash(&person1) == hash::hash(&person2));
61  * ```
62  */
63
64 #![experimental]
65
66 pub use core_collections::hash::{Hash, Hasher, Writer, hash, sip};
67
68 use core::kinds::Sized;
69 use default::Default;
70 use rand::Rng;
71 use rand;
72
73 /// `RandomSipHasher` computes the SipHash algorithm from a stream of bytes
74 /// initialized with random keys.
75 #[deriving(Clone)]
76 pub struct RandomSipHasher {
77     hasher: sip::SipHasher,
78 }
79
80 impl RandomSipHasher {
81     /// Construct a new `RandomSipHasher` that is initialized with random keys.
82     #[inline]
83     pub fn new() -> RandomSipHasher {
84         let mut r = rand::task_rng();
85         let r0 = r.gen();
86         let r1 = r.gen();
87         RandomSipHasher {
88             hasher: sip::SipHasher::new_with_keys(r0, r1),
89         }
90     }
91 }
92
93 impl Hasher<sip::SipState> for RandomSipHasher {
94     #[inline]
95     fn hash<Sized? T: Hash<sip::SipState>>(&self, value: &T) -> u64 {
96         self.hasher.hash(value)
97     }
98 }
99
100 impl Default for RandomSipHasher {
101     #[inline]
102     fn default() -> RandomSipHasher {
103         RandomSipHasher::new()
104     }
105 }