-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashes.c
103 lines (90 loc) · 2.4 KB
/
hashes.c
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
#include <stdint.h>
#include <stddef.h>
#include "hashes.h"
#ifdef __SSE4_2__
#include <x86intrin.h>
uint32_t crc32c(unsigned char *buf, size_t len) {
uint32_t l = 0;
for (int i = 0; i < len; i++) {
l = _mm_crc32_u8(l, *buf++);
}
return l;
}
#endif
// Compression function for Merkle-Damgard construction.
// This function is generated using the framework provided.
#define mix(h) ({ \
(h) ^= (h) >> 23; \
(h) *= 0x2127599bf4325c37ULL; \
(h) ^= (h) >> 47; })
uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
{
const uint64_t m = 0x880355f21e6d1965ULL;
const uint64_t *pos = (const uint64_t *)buf;
const uint64_t *end = pos + (len / 8);
const unsigned char *pos2;
uint64_t h = seed ^ (len * m);
uint64_t v;
while (pos != end) {
v = *pos++;
h ^= mix(v);
h *= m;
}
pos2 = (const unsigned char*)pos;
v = 0;
switch (len & 7) {
case 7: v ^= (uint64_t)pos2[6] << 48;
case 6: v ^= (uint64_t)pos2[5] << 40;
case 5: v ^= (uint64_t)pos2[4] << 32;
case 4: v ^= (uint64_t)pos2[3] << 24;
case 3: v ^= (uint64_t)pos2[2] << 16;
case 2: v ^= (uint64_t)pos2[1] << 8;
case 1: v ^= (uint64_t)pos2[0];
h ^= mix(v);
h *= m;
}
return mix(h);
}
uint32_t fasthash32(const void *buf, size_t len, uint32_t seed)
{
// the following trick converts the 64-bit hashcode to Fermat
// residue, which shall retain information from both the higher
// and lower parts of hashcode.
uint64_t h = fasthash64(buf, len, seed);
return h - (h >> 32);
}
#define FNV_PRIME_32 16777619
#define FNV_OFFSET_32 2166136261U
uint32_t FNV1A_32(const char *s, size_t len) {
uint32_t hash = FNV_OFFSET_32;
size_t i;
for(i = 0; i < len; i++) {
hash = hash ^ (s[i]);
hash = hash * FNV_PRIME_32;
}
return hash;
}
#define FNV_PRIME_64 (0x100000001b3ull)
#define FNV_OFFSET_64 (0xcbf29ce484222325ull)
uint64_t FNV1A_64(const char *s, size_t len) {
uint64_t hash = FNV_OFFSET_64;
size_t i;
for(i = 0; i < len; i++) {
hash = hash ^ (s[i]);
hash = hash * FNV_PRIME_64;
}
return hash;
}
uint32_t jenkins_one_at_a_time_hash(const uint8_t* key, size_t length) {
size_t i = 0;
uint32_t hash = 0;
while (i != length) {
hash += key[i++];
hash += hash << 10;
hash ^= hash >> 6;
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return hash;
}