-
Notifications
You must be signed in to change notification settings - Fork 0
/
spooky.h
117 lines (103 loc) · 3.1 KB
/
spooky.h
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
// SpookyHash: a 128-bit noncryptographic hash function
// By Bob Jenkins, public domain
// Oct 31 2010: alpha, framework + SpookyHash::Mix appears right
// Oct 11 2011: C version ported by Andi Kleen (andikleen@github)
// Oct 31 2011: alpha again, Mix only good to 2^^69 but rest appears right
// Dec 31 2011: beta, improved Mix, tested it for 2-bit deltas
// Feb 2 2012: production, same bits as beta
// Feb 5 2012: adjusted definitions of uint* to be more portable
// Mar 30 2012: 3 bytes/cycle, not 4. Alpha was 4 but wasn't
// thorough enough.
// Apr 27 2012: C version updated by Ziga Zupanec [email protected]
// (agiz@github)
// Oct 05 2013: Adjusted to SpookyV2, better formatting by Arno Wagner
//
// Up to 3 bytes/cycle for long messages. Reasonably fast for short messages.
// All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit.
//
// This was developed for and tested on 64-bit x86-compatible processors.
// It assumes the processor is little-endian. There is a macro
// controlling whether unaligned reads are allowed (by default they are).
// This should be an equally good hash on big-endian machines, but it will
// compute different results on them than on little-endian machines.
//
// Google's CityHash has similar specs to SpookyHash, and CityHash is faster
// on some platforms. MD4 and MD5 also have similar specs, but they are orders
// of magnitude slower. CRCs are two or more times slower, but unlike
// SpookyHash, they have nice math for combining the CRCs of pieces to form
// the CRCs of wholes. There are also cryptographic hashes, but those are even
// slower than MD5.
//
#ifndef _SPOOKY_H
#define _SPOOKY_H
#include <stdint.h>
#include <stddef.h>
#include <string>
#define SC_NUMVARS 12
#define SC_BLOCKSIZE (8 * SC_NUMVARS)
#define SC_BUFSIZE (2 * SC_BLOCKSIZE)
inline uint64_t rot64(uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
struct spooky_state
{
uint64_t m_data[2 * SC_NUMVARS];
uint64_t m_state[SC_NUMVARS];
size_t m_length;
unsigned char m_remainder;
};
void spooky_shorthash
(
const void *message,
size_t length,
uint64_t *hash1,
uint64_t *hash2
);
void spooky_init
(
struct spooky_state *state,
uint64_t hash1,
uint64_t hash2
);
void spooky_update
(
struct spooky_state *state,
const void *msg,
size_t len
);
void spooky_final
(
struct spooky_state *state,
uint64_t *hash1,
uint64_t *hash2
);
//hash1/2 doubles as input parameter for seed1/2 and output for hash1/2
void spooky_hash128
(
const void *message,
size_t length,
uint64_t *hash1,
uint64_t *hash2
);
uint64_t spooky_hash64
(
const void *message,
size_t len,
uint64_t seed
);
uint32_t spooky_hash32
(
const void *message,
size_t len,
uint32_t seed
);
inline uint64_t hash(const std::string &a, uint64_t seed) {
size_t str_len = a.size();
return spooky_hash64(a.c_str(), str_len, (uint64_t)str_len ^ seed);
}
inline uint64_t hash_string_with_seed(const char *a, uint64_t seed) {
size_t str_len = strlen(a);
return spooky_hash64((void *)a, str_len, (uint64_t)str_len ^ seed);
}
#endif