// Copyright 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0 > or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT >, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use super ::sip::{SipHasher, SipHasher13, SipHasher24};
use std::hash::{Hash, Hasher};
// Hash just the bytes of the slice, without length prefix
struct Bytes<
'a>(&' a [u8]);
impl <
'a> Hash for Bytes<' a> {
#[ allow(unused_must_use)]
fn hash<H: Hasher>(&
self , state: &
mut H) {
let Bytes(v) = *
self ;
state.write(v);
}
}
macro_rules! u8to64_le {
($buf:expr, $i:expr) => {
$buf[
0 + $i]
as u64
| ($buf[
1 + $i]
as u64) <<
8
| ($buf[
2 + $i]
as u64) <<
16
| ($buf[
3 + $i]
as u64) <<
24
| ($buf[
4 + $i]
as u64) <<
32
| ($buf[
5 + $i]
as u64) <<
40
| ($buf[
6 + $i]
as u64) <<
48
| ($buf[
7 + $i]
as u64) <<
56
};
($buf:expr, $i:expr, $len:expr) => {{
let mut t =
0 ;
let mut out =
0 ;
while t < $len {
out |= ($buf[t + $i]
as u64) << t *
8 ;
t +=
1 ;
}
out
}};
}
fn hash_with<H: Hasher, T: Hash>(
mut st: H, x: &T) -> u64 {
x.hash(&
mut st);
st.finish()
}
fn hash<T: Hash>(x: &T) -> u64 {
hash_with(SipHasher::new(), x)
}
#[ test]
#[ allow(unused_must_use)]
fn test_siphash_1_3() {
let vecs: [[u8;
8 ];
64 ] = [
[
0 xdc,
0 xc4,
0 x0f,
0 x05,
0 x58,
0 x01,
0 xac,
0 xab],
[
0 x93,
0 xca,
0 x57,
0 x7d,
0 xf3,
0 x9b,
0 xf4,
0 xc9],
[
0 x4d,
0 xd4,
0 xc7,
0 x4d,
0 x02,
0 x9b,
0 xcb,
0 x82],
[
0 xfb,
0 xf7,
0 xdd,
0 xe7,
0 xb8,
0 x0a,
0 xf8,
0 x8b],
[
0 x28,
0 x83,
0 xd3,
0 x88,
0 x60,
0 x57,
0 x75,
0 xcf],
[
0 x67,
0 x3b,
0 x53,
0 x49,
0 x2f,
0 xd5,
0 xf9,
0 xde],
[
0 xa7,
0 x22,
0 x9f,
0 xc5,
0 x50,
0 x2b,
0 x0d,
0 xc5],
[
0 x40,
0 x11,
0 xb1,
0 x9b,
0 x98,
0 x7d,
0 x92,
0 xd3],
[
0 x8e,
0 x9a,
0 x29,
0 x8d,
0 x11,
0 x95,
0 x90,
0 x36],
[
0 xe4,
0 x3d,
0 x06,
0 x6c,
0 xb3,
0 x8e,
0 xa4,
0 x25],
[
0 x7f,
0 x09,
0 xff,
0 x92,
0 xee,
0 x85,
0 xde,
0 x79],
[
0 x52,
0 xc3,
0 x4d,
0 xf9,
0 xc1,
0 x18,
0 xc1,
0 x70],
[
0 xa2,
0 xd9,
0 xb4,
0 x57,
0 xb1,
0 x84,
0 xa3,
0 x78],
[
0 xa7,
0 xff,
0 x29,
0 x12,
0 x0c,
0 x76,
0 x6f,
0 x30],
[
0 x34,
0 x5d,
0 xf9,
0 xc0,
0 x11,
0 xa1,
0 x5a,
0 x60],
[
0 x56,
0 x99,
0 x51,
0 x2a,
0 x6d,
0 xd8,
0 x20,
0 xd3],
[
0 x66,
0 x8b,
0 x90,
0 x7d,
0 x1a,
0 xdd,
0 x4f,
0 xcc],
[
0 x0c,
0 xd8,
0 xdb,
0 x63,
0 x90,
0 x68,
0 xf2,
0 x9c],
[
0 x3e,
0 xe6,
0 x73,
0 xb4,
0 x9c,
0 x38,
0 xfc,
0 x8f],
[
0 x1c,
0 x7d,
0 x29,
0 x8d,
0 xe5,
0 x9d,
0 x1f,
0 xf2],
[
0 x40,
0 xe0,
0 xcc,
0 xa6,
0 x46,
0 x2f,
0 xdc,
0 xc0],
[
0 x44,
0 xf8,
0 x45,
0 x2b,
0 xfe,
0 xab,
0 x92,
0 xb9],
[
0 x2e,
0 x87,
0 x20,
0 xa3,
0 x9b,
0 x7b,
0 xfe,
0 x7f],
[
0 x23,
0 xc1,
0 xe6,
0 xda,
0 x7f,
0 x0e,
0 x5a,
0 x52],
[
0 x8c,
0 x9c,
0 x34,
0 x67,
0 xb2,
0 xae,
0 x64,
0 xf4],
[
0 x79,
0 x09,
0 x5b,
0 x70,
0 x28,
0 x59,
0 xcd,
0 x45],
[
0 xa5,
0 x13,
0 x99,
0 xca,
0 xe3,
0 x35,
0 x3e,
0 x3a],
[
0 x35,
0 x3b,
0 xde,
0 x4a,
0 x4e,
0 xc7,
0 x1d,
0 xa9],
[
0 x0d,
0 xd0,
0 x6c,
0 xef,
0 x02,
0 xed,
0 x0b,
0 xfb],
[
0 xf4,
0 xe1,
0 xb1,
0 x4a,
0 xb4,
0 x3c,
0 xd9,
0 x88],
[
0 x63,
0 xe6,
0 xc5,
0 x43,
0 xd6,
0 x11,
0 x0f,
0 x54],
[
0 xbc,
0 xd1,
0 x21,
0 x8c,
0 x1f,
0 xdd,
0 x70,
0 x23],
[
0 x0d,
0 xb6,
0 xa7,
0 x16,
0 x6c,
0 x7b,
0 x15,
0 x81],
[
0 xbf,
0 xf9,
0 x8f,
0 x7a,
0 xe5,
0 xb9,
0 x54,
0 x4d],
[
0 x3e,
0 x75,
0 x2a,
0 x1f,
0 x78,
0 x12,
0 x9f,
0 x75],
[
0 x91,
0 x6b,
0 x18,
0 xbf,
0 xbe,
0 xa3,
0 xa1,
0 xce],
[
0 x06,
0 x62,
0 xa2,
0 xad,
0 xd3,
0 x08,
0 xf5,
0 x2c],
[
0 x57,
0 x30,
0 xc3,
0 xa3,
0 x2d,
0 x1c,
0 x10,
0 xb6],
[
0 xa1,
0 x36,
0 x3a,
0 xae,
0 x96,
0 x74,
0 xf4,
0 xb3],
[
0 x92,
0 x83,
0 x10,
0 x7b,
0 x54,
0 x57,
0 x6b,
0 x62],
[
0 x31,
0 x15,
0 xe4,
0 x99,
0 x32,
0 x36,
0 xd2,
0 xc1],
[
0 x44,
0 xd9,
0 x1a,
0 x3f,
0 x92,
0 xc1,
0 x7c,
0 x66],
[
0 x25,
0 x88,
0 x13,
0 xc8,
0 xfe,
0 x4f,
0 x70,
0 x65],
[
0 xa6,
0 x49,
0 x89,
0 xc2,
0 xd1,
0 x80,
0 xf2,
0 x24],
[
0 x6b,
0 x87,
0 xf8,
0 xfa,
0 xed,
0 x1c,
0 xca,
0 xc2],
[
0 x96,
0 x21,
0 x04,
0 x9f,
0 xfc,
0 x4b,
0 x16,
0 xc2],
[
0 x23,
0 xd6,
0 xb1,
0 x68,
0 x93,
0 x9c,
0 x6e,
0 xa1],
[
0 xfd,
0 x14,
0 x51,
0 x8b,
0 x9c,
0 x16,
0 xfb,
0 x49],
[
0 x46,
0 x4c,
0 x07,
0 xdf,
0 xf8,
0 x43,
0 x31,
0 x9f],
[
0 xb3,
0 x86,
0 xcc,
0 x12,
0 x24,
0 xaf,
0 xfd,
0 xc6],
[
0 x8f,
0 x09,
0 x52,
0 x0a,
0 xd1,
0 x49,
0 xaf,
0 x7e],
[
0 x9a,
0 x2f,
0 x29,
0 x9d,
0 x55,
0 x13,
0 xf3,
0 x1c],
[
0 x12,
0 x1f,
0 xf4,
0 xa2,
0 xdd,
0 x30,
0 x4a,
0 xc4],
[
0 xd0,
0 x1e,
0 xa7,
0 x43,
0 x89,
0 xe9,
0 xfa,
0 x36],
[
0 xe6,
0 xbc,
0 xf0,
0 x73,
0 x4c,
0 xb3,
0 x8f,
0 x31],
[
0 x80,
0 xe9,
0 xa7,
0 x70,
0 x36,
0 xbf,
0 x7a,
0 xa2],
[
0 x75,
0 x6d,
0 x3c,
0 x24,
0 xdb,
0 xc0,
0 xbc,
0 xb4],
[
0 x13,
0 x15,
0 xb7,
0 xfd,
0 x52,
0 xd8,
0 xf8,
0 x23],
[
0 x08,
0 x8a,
0 x7d,
0 xa6,
0 x4d,
0 x5f,
0 x03,
0 x8f],
[
0 x48,
0 xf1,
0 xe8,
0 xb7,
0 xe5,
0 xd0,
0 x9c,
0 xd8],
[
0 xee,
0 x44,
0 xa6,
0 xf7,
0 xbc,
0 xe6,
0 xf4,
0 xf6],
[
0 xf2,
0 x37,
0 x18,
0 x0f,
0 xd8,
0 x9a,
0 xc5,
0 xae],
[
0 xe0,
0 x94,
0 x66,
0 x4b,
0 x15,
0 xf6,
0 xb2,
0 xc3],
[
0 xa8,
0 xb3,
0 xbb,
0 xb7,
0 x62,
0 x90,
0 x19,
0 x9d],
];
let k0 =
0 x_07_06_05_04_03_02_01_00;
let k1 =
0 x_0f_0e_0d_0c_0b_0a_09_08;
let mut buf = Vec::new();
let mut t =
0 ;
let mut state_inc = SipHasher13::new_with_keys(k0, k1);
while t <
64 {
let vec = u8to64_le!(vecs[t],
0 );
let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
assert_eq!(vec, out);
let full = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
let i = state_inc.finish();
assert_eq!(full, i);
assert_eq!(full, vec);
buf.push(t
as u8);
Hasher::write(&
mut state_inc, &[t
as u8]);
t +=
1 ;
}
}
#[ test]
#[ allow(unused_must_use)]
fn test_siphash_2_4() {
let vecs: [[u8;
8 ];
64 ] = [
[
0 x31,
0 x0e,
0 x0e,
0 xdd,
0 x47,
0 xdb,
0 x6f,
0 x72],
[
0 xfd,
0 x67,
0 xdc,
0 x93,
0 xc5,
0 x39,
0 xf8,
0 x74],
[
0 x5a,
0 x4f,
0 xa9,
0 xd9,
0 x09,
0 x80,
0 x6c,
0 x0d],
[
0 x2d,
0 x7e,
0 xfb,
0 xd7,
0 x96,
0 x66,
0 x67,
0 x85],
[
0 xb7,
0 x87,
0 x71,
0 x27,
0 xe0,
0 x94,
0 x27,
0 xcf],
[
0 x8d,
0 xa6,
0 x99,
0 xcd,
0 x64,
0 x55,
0 x76,
0 x18],
[
0 xce,
0 xe3,
0 xfe,
0 x58,
0 x6e,
0 x46,
0 xc9,
0 xcb],
[
0 x37,
0 xd1,
0 x01,
0 x8b,
0 xf5,
0 x00,
0 x02,
0 xab],
[
0 x62,
0 x24,
0 x93,
0 x9a,
0 x79,
0 xf5,
0 xf5,
0 x93],
[
0 xb0,
0 xe4,
0 xa9,
0 x0b,
0 xdf,
0 x82,
0 x00,
0 x9e],
[
0 xf3,
0 xb9,
0 xdd,
0 x94,
0 xc5,
0 xbb,
0 x5d,
0 x7a],
[
0 xa7,
0 xad,
0 x6b,
0 x22,
0 x46,
0 x2f,
0 xb3,
0 xf4],
[
0 xfb,
0 xe5,
0 x0e,
0 x86,
0 xbc,
0 x8f,
0 x1e,
0 x75],
[
0 x90,
0 x3d,
0 x84,
0 xc0,
0 x27,
0 x56,
0 xea,
0 x14],
[
0 xee,
0 xf2,
0 x7a,
0 x8e,
0 x90,
0 xca,
0 x23,
0 xf7],
[
0 xe5,
0 x45,
0 xbe,
0 x49,
0 x61,
0 xca,
0 x29,
0 xa1],
[
0 xdb,
0 x9b,
0 xc2,
0 x57,
0 x7f,
0 xcc,
0 x2a,
0 x3f],
[
0 x94,
0 x47,
0 xbe,
0 x2c,
0 xf5,
0 xe9,
0 x9a,
0 x69],
[
0 x9c,
0 xd3,
0 x8d,
0 x96,
0 xf0,
0 xb3,
0 xc1,
0 x4b],
[
0 xbd,
0 x61,
0 x79,
0 xa7,
0 x1d,
0 xc9,
0 x6d,
0 xbb],
[
0 x98,
0 xee,
0 xa2,
0 x1a,
0 xf2,
0 x5c,
0 xd6,
0 xbe],
[
0 xc7,
0 x67,
0 x3b,
0 x2e,
0 xb0,
0 xcb,
0 xf2,
0 xd0],
[
0 x88,
0 x3e,
0 xa3,
0 xe3,
0 x95,
0 x67,
0 x53,
0 x93],
[
0 xc8,
0 xce,
0 x5c,
0 xcd,
0 x8c,
0 x03,
0 x0c,
0 xa8],
[
0 x94,
0 xaf,
0 x49,
0 xf6,
0 xc6,
0 x50,
0 xad,
0 xb8],
[
0 xea,
0 xb8,
0 x85,
0 x8a,
0 xde,
0 x92,
0 xe1,
0 xbc],
[
0 xf3,
0 x15,
0 xbb,
0 x5b,
0 xb8,
0 x35,
0 xd8,
0 x17],
[
0 xad,
0 xcf,
0 x6b,
0 x07,
0 x63,
0 x61,
0 x2e,
0 x2f],
[
0 xa5,
0 xc9,
0 x1d,
0 xa7,
0 xac,
0 xaa,
0 x4d,
0 xde],
[
0 x71,
0 x65,
0 x95,
0 x87,
0 x66,
0 x50,
0 xa2,
0 xa6],
[
0 x28,
0 xef,
0 x49,
0 x5c,
0 x53,
0 xa3,
0 x87,
0 xad],
[
0 x42,
0 xc3,
0 x41,
0 xd8,
0 xfa,
0 x92,
0 xd8,
0 x32],
[
0 xce,
0 x7c,
0 xf2,
0 x72,
0 x2f,
0 x51,
0 x27,
0 x71],
[
0 xe3,
0 x78,
0 x59,
0 xf9,
0 x46,
0 x23,
0 xf3,
0 xa7],
[
0 x38,
0 x12,
0 x05,
0 xbb,
0 x1a,
0 xb0,
0 xe0,
0 x12],
[
0 xae,
0 x97,
0 xa1,
0 x0f,
0 xd4,
0 x34,
0 xe0,
0 x15],
[
0 xb4,
0 xa3,
0 x15,
0 x08,
0 xbe,
0 xff,
0 x4d,
0 x31],
[
0 x81,
0 x39,
0 x62,
0 x29,
0 xf0,
0 x90,
0 x79,
0 x02],
[
0 x4d,
0 x0c,
0 xf4,
0 x9e,
0 xe5,
0 xd4,
0 xdc,
0 xca],
[
0 x5c,
0 x73,
0 x33,
0 x6a,
0 x76,
0 xd8,
0 xbf,
0 x9a],
[
0 xd0,
0 xa7,
0 x04,
0 x53,
0 x6b,
0 xa9,
0 x3e,
0 x0e],
[
0 x92,
0 x59,
0 x58,
0 xfc,
0 xd6,
0 x42,
0 x0c,
0 xad],
[
0 xa9,
0 x15,
0 xc2,
0 x9b,
0 xc8,
0 x06,
0 x73,
0 x18],
[
0 x95,
0 x2b,
0 x79,
0 xf3,
0 xbc,
0 x0a,
0 xa6,
0 xd4],
[
0 xf2,
0 x1d,
0 xf2,
0 xe4,
0 x1d,
0 x45,
0 x35,
0 xf9],
[
0 x87,
0 x57,
0 x75,
0 x19,
0 x04,
0 x8f,
0 x53,
0 xa9],
[
0 x10,
0 xa5,
0 x6c,
0 xf5,
0 xdf,
0 xcd,
0 x9a,
0 xdb],
[
0 xeb,
0 x75,
0 x09,
0 x5c,
0 xcd,
0 x98,
0 x6c,
0 xd0],
[
0 x51,
0 xa9,
0 xcb,
0 x9e,
0 xcb,
0 xa3,
0 x12,
0 xe6],
[
0 x96,
0 xaf,
0 xad,
0 xfc,
0 x2c,
0 xe6,
0 x66,
0 xc7],
[
0 x72,
0 xfe,
0 x52,
0 x97,
0 x5a,
0 x43,
0 x64,
0 xee],
[
0 x5a,
0 x16,
0 x45,
0 xb2,
0 x76,
0 xd5,
0 x92,
0 xa1],
[
0 xb2,
0 x74,
0 xcb,
0 x8e,
0 xbf,
0 x87,
0 x87,
0 x0a],
[
0 x6f,
0 x9b,
0 xb4,
0 x20,
0 x3d,
0 xe7,
0 xb3,
0 x81],
[
0 xea,
0 xec,
0 xb2,
0 xa3,
0 x0b,
0 x22,
0 xa8,
0 x7f],
[
0 x99,
0 x24,
0 xa4,
0 x3c,
0 xc1,
0 x31,
0 x57,
0 x24],
[
0 xbd,
0 x83,
0 x8d,
0 x3a,
0 xaf,
0 xbf,
0 x8d,
0 xb7],
[
0 x0b,
0 x1a,
0 x2a,
0 x32,
0 x65,
0 xd5,
0 x1a,
0 xea],
[
0 x13,
0 x50,
0 x79,
0 xa3,
0 x23,
0 x1c,
0 xe6,
0 x60],
[
0 x93,
0 x2b,
0 x28,
0 x46,
0 xe4,
0 xd7,
0 x06,
0 x66],
[
0 xe1,
0 x91,
0 x5f,
0 x5c,
0 xb1,
0 xec,
0 xa4,
0 x6c],
[
0 xf3,
0 x25,
0 x96,
0 x5c,
0 xa1,
0 x6d,
0 x62,
0 x9f],
[
0 x57,
0 x5f,
0 xf2,
0 x8e,
0 x60,
0 x38,
0 x1b,
0 xe5],
[
0 x72,
0 x45,
0 x06,
0 xeb,
0 x4c,
0 x32,
0 x8a,
0 x95],
];
let k0 =
0 x_07_06_05_04_03_02_01_00;
let k1 =
0 x_0f_0e_0d_0c_0b_0a_09_08;
let mut buf = Vec::new();
let mut t =
0 ;
let mut state_inc = SipHasher24::new_with_keys(k0, k1);
while t <
64 {
let vec = u8to64_le!(vecs[t],
0 );
let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
assert_eq!(vec, out);
let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
let i = state_inc.finish();
assert_eq!(full, i);
assert_eq!(full, vec);
buf.push(t
as u8);
Hasher::write(&
mut state_inc, &[t
as u8]);
t +=
1 ;
}
}
#[ test]
fn test_hash_idempotent() {
let val64 =
0 xdead_beef_dead_beef_u64;
assert_eq!(hash(&val64), hash(&val64));
let val32 =
0 xdeadbeef_u32;
assert_eq!(hash(&val32), hash(&val32));
}
#[ test]
fn test_hash_no_bytes_dropped_64() {
let val =
0 xdead_beef_dead_beef_u64;
assert_ne!(hash(&val), hash(&zero_byte(val,
0 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
1 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
2 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
3 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
4 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
5 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
6 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
7 )));
fn zero_byte(val: u64, byte: usize) -> u64 {
assert!(byte <
8 );
val & !(
0 xff << (byte *
8 ))
}
}
#[ test]
fn test_hash_no_bytes_dropped_32() {
let val =
0 xdeadbeef_u32;
assert_ne!(hash(&val), hash(&zero_byte(val,
0 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
1 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
2 )));
assert_ne!(hash(&val), hash(&zero_byte(val,
3 )));
fn zero_byte(val: u32, byte: usize) -> u32 {
assert!(byte <
4 );
val & !(
0 xff << (byte *
8 ))
}
}
#[ test]
fn test_hash_no_concat_alias() {
let s = (
"aa" ,
"bb" );
let t = (
"aabb" ,
"" );
let u = (
"a" ,
"abb" );
assert!(s != t && t != u);
assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
let u = [
1 ,
0 ,
0 ,
0 ];
let v = (&u[..
1 ], &u[
1 ..
3 ], &u[
3 ..]);
let w = (&u[..], &u[
4 ..
4 ], &u[
4 ..
4 ]);
assert_ne!(v, w);
assert_ne!(hash(&v), hash(&w));
}
#[ test]
fn test_hash_serde() {
let val64 =
0 xdead_beef_dead_beef_u64;
let hash = hash(&val64);
let serialized = serde_json::to_string(&hash).unwrap();
let deserialized: u64 = serde_json::from_str(&serialized).unwrap();
assert_eq!(hash, deserialized);
}
Messung V0.5 in Prozent C=69 H=92 G=80
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-19)
¤
*© Formatika GbR, Deutschland