// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Generic hashing support. //! //! This module provides a generic way to compute the hash of a value. The //! simplest way to make a type hashable is to use `#[derive(Hash)]`: //! //! # Examples //! //! ```rust //! use std::hash::{Hash, SipHasher, Hasher}; //! //! #[derive(Hash)] //! struct Person { //! id: u32, //! name: String, //! phone: u64, //! } //! //! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 }; //! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 }; //! //! assert!(hash(&person1) != hash(&person2)); //! //! fn hash(t: &T) -> u64 { //! let mut s = SipHasher::new(); //! t.hash(&mut s); //! s.finish() //! } //! ``` //! //! If you need more control over how a value is hashed, you need to implement //! the `Hash` trait: //! //! ```rust //! use std::hash::{Hash, Hasher, SipHasher}; //! //! struct Person { //! id: u32, //! # #[allow(dead_code)] //! name: String, //! phone: u64, //! } //! //! impl Hash for Person { //! fn hash(&self, state: &mut H) { //! self.id.hash(state); //! self.phone.hash(state); //! } //! } //! //! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 }; //! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 }; //! //! assert_eq!(hash(&person1), hash(&person2)); //! //! fn hash(t: &T) -> u64 { //! let mut s = SipHasher::new(); //! t.hash(&mut s); //! s.finish() //! } //! ``` #![stable(feature = "rust1", since = "1.0.0")] use prelude::v1::*; use fmt; use marker; use mem; #[stable(feature = "rust1", since = "1.0.0")] pub use self::sip::SipHasher; #[unstable(feature = "sip_hash_13", issue = "29754")] pub use self::sip::{SipHasher13, SipHasher24}; mod sip; /// A hashable type. /// /// The `H` type parameter is an abstract hash state that is used by the `Hash` /// to compute the hash. /// /// If you are also implementing `Eq`, there is an additional property that /// is important: /// /// ```text /// k1 == k2 -> hash(k1) == hash(k2) /// ``` /// /// In other words, if two keys are equal, their hashes should also be equal. /// `HashMap` and `HashSet` both rely on this behavior. /// /// ## Derivable /// /// This trait can be used with `#[derive]` if all fields implement `Hash`. /// When `derive`d, the resulting hash will be the combination of the values /// from calling `.hash()` on each field. /// /// ## How can I implement `Hash`? /// /// If you need more control over how a value is hashed, you need to implement /// the `Hash` trait: /// /// ``` /// use std::hash::{Hash, Hasher}; /// /// struct Person { /// id: u32, /// name: String, /// phone: u64, /// } /// /// impl Hash for Person { /// fn hash(&self, state: &mut H) { /// self.id.hash(state); /// self.phone.hash(state); /// } /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Hash { /// Feeds this value into the state given, updating the hasher as necessary. #[stable(feature = "rust1", since = "1.0.0")] fn hash(&self, state: &mut H); /// Feeds a slice of this type into the state provided. #[stable(feature = "hash_slice", since = "1.3.0")] fn hash_slice(data: &[Self], state: &mut H) where Self: Sized { for piece in data { piece.hash(state); } } } /// A trait which represents the ability to hash an arbitrary stream of bytes. #[stable(feature = "rust1", since = "1.0.0")] pub trait Hasher { /// Completes a round of hashing, producing the output hash generated. #[stable(feature = "rust1", since = "1.0.0")] fn finish(&self) -> u64; /// Writes some data into this `Hasher` #[stable(feature = "rust1", since = "1.0.0")] fn write(&mut self, bytes: &[u8]); /// Write a single `u8` into this hasher #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_u8(&mut self, i: u8) { self.write(&[i]) } /// Write a single `u16` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_u16(&mut self, i: u16) { self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) }) } /// Write a single `u32` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_u32(&mut self, i: u32) { self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) }) } /// Write a single `u64` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_u64(&mut self, i: u64) { self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) }) } /// Write a single `usize` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_usize(&mut self, i: usize) { let bytes = unsafe { ::slice::from_raw_parts(&i as *const usize as *const u8, mem::size_of::()) }; self.write(bytes); } /// Write a single `i8` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) } /// Write a single `i16` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) } /// Write a single `i32` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) } /// Write a single `i64` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) } /// Write a single `isize` into this hasher. #[inline] #[stable(feature = "hasher_write", since = "1.3.0")] fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) } } /// A `BuildHasher` is typically used as a factory for instances of `Hasher` /// which a `HashMap` can then use to hash keys independently. /// /// Note that for each instance of `BuildHasher`, the created hashers should be /// identical. That is, if the same stream of bytes is fed into each hasher, the /// same output will also be generated. #[stable(since = "1.7.0", feature = "build_hasher")] pub trait BuildHasher { /// Type of the hasher that will be created. #[stable(since = "1.7.0", feature = "build_hasher")] type Hasher: Hasher; /// Creates a new hasher. /// /// # Examples /// /// ``` /// use std::collections::hash_map::RandomState; /// use std::hash::BuildHasher; /// /// let s = RandomState::new(); /// let new_s = s.build_hasher(); /// ``` #[stable(since = "1.7.0", feature = "build_hasher")] fn build_hasher(&self) -> Self::Hasher; } /// A structure which implements `BuildHasher` for all `Hasher` types which also /// implement `Default`. /// /// This struct is 0-sized and does not need construction. #[stable(since = "1.7.0", feature = "build_hasher")] pub struct BuildHasherDefault(marker::PhantomData); #[stable(since = "1.9.0", feature = "core_impl_debug")] impl fmt::Debug for BuildHasherDefault { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("BuildHasherDefault") } } #[stable(since = "1.7.0", feature = "build_hasher")] impl BuildHasher for BuildHasherDefault { type Hasher = H; fn build_hasher(&self) -> H { H::default() } } #[stable(since = "1.7.0", feature = "build_hasher")] impl Clone for BuildHasherDefault { fn clone(&self) -> BuildHasherDefault { BuildHasherDefault(marker::PhantomData) } } #[stable(since = "1.7.0", feature = "build_hasher")] impl Default for BuildHasherDefault { fn default() -> BuildHasherDefault { BuildHasherDefault(marker::PhantomData) } } ////////////////////////////////////////////////////////////////////////////// mod impls { use prelude::v1::*; use mem; use slice; use super::*; macro_rules! impl_write { ($(($ty:ident, $meth:ident),)*) => {$( #[stable(feature = "rust1", since = "1.0.0")] impl Hash for $ty { fn hash(&self, state: &mut H) { state.$meth(*self) } fn hash_slice(data: &[$ty], state: &mut H) { let newlen = data.len() * mem::size_of::<$ty>(); let ptr = data.as_ptr() as *const u8; state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) } } )*} } impl_write! { (u8, write_u8), (u16, write_u16), (u32, write_u32), (u64, write_u64), (usize, write_usize), (i8, write_i8), (i16, write_i16), (i32, write_i32), (i64, write_i64), (isize, write_isize), } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for bool { fn hash(&self, state: &mut H) { state.write_u8(*self as u8) } } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for char { fn hash(&self, state: &mut H) { state.write_u32(*self as u32) } } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for str { fn hash(&self, state: &mut H) { state.write(self.as_bytes()); state.write_u8(0xff) } } macro_rules! impl_hash_tuple { () => ( #[stable(feature = "rust1", since = "1.0.0")] impl Hash for () { fn hash(&self, _state: &mut H) {} } ); ( $($name:ident)+) => ( #[stable(feature = "rust1", since = "1.0.0")] impl<$($name: Hash),*> Hash for ($($name,)*) { #[allow(non_snake_case)] fn hash(&self, state: &mut S) { let ($(ref $name,)*) = *self; $($name.hash(state);)* } } ); } impl_hash_tuple! {} impl_hash_tuple! { A } impl_hash_tuple! { A B } impl_hash_tuple! { A B C } impl_hash_tuple! { A B C D } impl_hash_tuple! { A B C D E } impl_hash_tuple! { A B C D E F } impl_hash_tuple! { A B C D E F G } impl_hash_tuple! { A B C D E F G H } impl_hash_tuple! { A B C D E F G H I } impl_hash_tuple! { A B C D E F G H I J } impl_hash_tuple! { A B C D E F G H I J K } impl_hash_tuple! { A B C D E F G H I J K L } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for [T] { fn hash(&self, state: &mut H) { self.len().hash(state); Hash::hash_slice(self, state) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized + Hash> Hash for &'a T { fn hash(&self, state: &mut H) { (**self).hash(state); } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized + Hash> Hash for &'a mut T { fn hash(&self, state: &mut H) { (**self).hash(state); } } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for *const T { fn hash(&self, state: &mut H) { state.write_usize(*self as usize) } } #[stable(feature = "rust1", since = "1.0.0")] impl Hash for *mut T { fn hash(&self, state: &mut H) { state.write_usize(*self as usize) } } }