hash256_std_hasher/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
16
17#[macro_use]
18extern crate crunchy;
19
20#[cfg(feature = "std")]
21use std::hash;
22
23#[cfg(not(feature = "std"))]
24use core::hash;
25
26#[derive(Default)]
29pub struct Hash256StdHasher {
30 prefix: u64,
31}
32
33impl hash::Hasher for Hash256StdHasher {
34 #[inline]
35 fn finish(&self) -> u64 {
36 self.prefix
37 }
38
39 #[inline]
40 #[allow(unused_assignments)]
41 fn write(&mut self, bytes: &[u8]) {
42 debug_assert!(bytes.len() == 4 || bytes.len() == 8 || bytes.len() == 32);
45 if bytes.len() < 32 { return }
46
47 let mut bytes_ptr = bytes.as_ptr();
48 let mut prefix_ptr = &mut self.prefix as *mut u64 as *mut u8;
49
50 unroll! {
51 for _i in 0..8 {
52 unsafe {
53 *prefix_ptr ^= (*bytes_ptr ^ *bytes_ptr.offset(8)) ^ (*bytes_ptr.offset(16) ^ *bytes_ptr.offset(24));
54 bytes_ptr = bytes_ptr.offset(1);
55 prefix_ptr = prefix_ptr.offset(1);
56 }
57 }
58 }
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use hash::Hasher;
65 use super::Hash256StdHasher;
66
67 #[test]
68 fn it_works() {
69 let mut bytes = [32u8; 32];
70 bytes[0] = 15;
71 let mut hasher = Hash256StdHasher::default();
72 hasher.write(&bytes);
73 assert_eq!(hasher.prefix, 47);
74 }
75}