forked from rurban/smhasher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfloppsyhash.cpp
90 lines (66 loc) · 1.94 KB
/
floppsyhash.cpp
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
// Copyright 2020 Cris Stringfellow
// Licensed under GPL-3.0
// https://github.com/dosyago/floppsy
#define _USE_MATH_DEFINES
#include <math.h>
#include "floppsyhash.h"
#if defined(_MSC_VER)
#define FORCE_INLINE __forceinline
// Other compilers
#else // defined(_MSC_VER)
#define FORCE_INLINE inline __attribute__((always_inline))
#endif // !defined(_MSC_VER)
//---------
// Q function : Continued Egyptian Fraction update function
FORCE_INLINE void q ( double * state, double key_val,
double numerator, double denominator )
{
state[0] += numerator / denominator;
state[0] = 1.0 / state[0];
state[1] += key_val + M_PI;
state[1] = numerator / state[1];
}
//---------
// round function : process the message
FORCE_INLINE void round ( const uint8_t * msg, long len,
double * state )
{
double numerator = 1.0;
// Loop
for( long i = 0; i < len; i++ ) {
double val = (double)msg[i];
double denominator = (M_E * val + i + 1) / state[1];
q( state, val, numerator, denominator );
numerator = denominator + 1;
}
}
//---------
// setup function : setup the state
FORCE_INLINE void setup ( double * state, double init = 0 )
{
state[0] += init != 0 ? pow(init + 1.0/init, 1.0/3) : 3.0;
state[1] += init != 0 ? pow(init + 1.0/init, 1.0/7) : 1.0/7;
}
//---------
// floppsyhash
// with 64 bit continued egyptian fractions
void floppsyhash_64 ( const void * key, int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t *)key;
uint8_t buf [16];
double * state = (double*)buf;
uint32_t * state32 = (uint32_t*)buf;
double seed32 = (double)seed;
uint8_t * seedbuf;
seedbuf = (uint8_t *)&seed;
setup( state, seed32 );
round( seedbuf, 4, state );
round( data, len, state );
uint8_t output [8];
uint32_t * h = (uint32_t*)output;
h[0] = state32[0] + state32[3];
h[1] = state32[1] + state32[2];
((uint32_t*)out)[0] = h[0];
((uint32_t*)out)[1] = h[1];
}