"Fossies" - the Fresh Open Source Software Archive 
Member "n2n-3.1.1/src/pearson.c" (31 Mar 2022, 5255 Bytes) of package /linux/misc/n2n-3.1.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "pearson.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
3.0_vs_3.1.1.
1 /**
2 * (C) 2007-22 - ntop.org and contributors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not see see <http://www.gnu.org/licenses/>
16 *
17 */
18
19
20 // taken from https://github.com/Logan007/pearsonB
21 // this is free and unencumbered software released into the public domain
22
23
24 #include "pearson.h"
25
26
27 // Christopher Wellons' triple32 from https://github.com/skeeto/hash-prospector
28 // published under The Unlicense
29 #define permute32(in) \
30 in ^= in >> 17; \
31 in *= 0xed5ad4bb; \
32 in ^= in >> 11; \
33 in *= 0xac4c1b51; \
34 in ^= in >> 15; \
35 in *= 0x31848bab; \
36 in ^= in >> 14
37
38 // David Stafford's Mix13 from http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
39 // the author clarified via eMail that this of his work is released to the public domain
40 #define permute64(in) \
41 in ^= (in >> 30); \
42 in *= 0xbf58476d1ce4e5b9; \
43 in ^= (in >> 27); \
44 in *= 0x94d049bb133111eb; \
45 in ^= (in >> 31)
46
47 #define dec1(in) \
48 in--
49
50 #define dec2(in) \
51 dec1(in); \
52 dec1(in)
53
54 #define dec3(in) \
55 dec2(in); \
56 dec1(in)
57
58 #define dec4(in) \
59 dec3(in); \
60 dec1(in)
61
62 #define hash_round(hash, in, part) \
63 hash##part ^= in; \
64 dec##part(hash##part); \
65 permute64(hash##part)
66
67
68 void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len) {
69
70 uint64_t *current;
71 current = (uint64_t*)in;
72 uint64_t org_len = len;
73 uint64_t hash1 = 0;
74 uint64_t hash2 = 0;
75 uint64_t hash3 = 0;
76 uint64_t hash4 = 0;
77
78 while (len > 7) {
79 // digest words little endian first
80 hash_round(hash, le64toh(*current), 1);
81 hash_round(hash, le64toh(*current), 2);
82 hash_round(hash, le64toh(*current), 3);
83 hash_round(hash, le64toh(*current), 4);
84
85 current++;
86 len-=8;
87 }
88
89 // handle the rest
90 hash1 = ~hash1;
91 hash2 = ~hash2;
92 hash3 = ~hash3;
93 hash4 = ~hash4;
94
95 while(len) {
96 // byte-wise, no endianess
97 hash_round(hash, *(uint8_t*)current, 1);
98 hash_round(hash, *(uint8_t*)current, 2);
99 hash_round(hash, *(uint8_t*)current, 3);
100 hash_round(hash, *(uint8_t*)current, 4);
101
102 current = (uint64_t*)((uint8_t*)current + 1);
103 len--;
104 }
105
106 // digest length
107 hash1 = ~hash1;
108 hash2 = ~hash2;
109 hash3 = ~hash3;
110 hash4 = ~hash4;
111
112 hash_round(hash, org_len, 1);
113 hash_round(hash, org_len, 2);
114 hash_round(hash, org_len, 3);
115 hash_round(hash, org_len, 4);
116
117 // hash string is stored big endian, the natural way to read
118 uint64_t *o;
119 o = (uint64_t*)out;
120 *o = htobe64(hash4);
121 o++;
122 *o = htobe64(hash3);
123 o++;
124 *o = htobe64(hash2);
125 o++;
126 *o = htobe64(hash1);
127 }
128
129
130 void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len) {
131
132 uint64_t *current;
133 current = (uint64_t*)in;
134 uint64_t org_len = len;
135 uint64_t hash1 = 0;
136 uint64_t hash2 = 0;
137
138 while (len > 7) {
139 // digest words little endian first
140 hash_round(hash, le64toh(*current), 1);
141 hash_round(hash, le64toh(*current), 2);
142
143 current++;
144 len-=8;
145 }
146
147 // handle the rest
148 hash1 = ~hash1;
149 hash2 = ~hash2;
150
151 while(len) {
152 // byte-wise, no endianess
153 hash_round(hash, *(uint8_t*)current, 1);
154 hash_round(hash, *(uint8_t*)current, 2);
155
156 current = (uint64_t*)((uint8_t*)current + 1);
157 len--;
158 }
159
160 // digest length
161 hash1 = ~hash1;
162 hash2 = ~hash2;
163
164 hash_round(hash, org_len, 1);
165 hash_round(hash, org_len, 2);
166
167 // hash string is stored big endian, the natural way to read
168 uint64_t *o;
169 o = (uint64_t*)out;
170 *o = htobe64(hash2);
171 o++;
172 *o = htobe64(hash1);
173 }
174
175
176 uint64_t pearson_hash_64 (const uint8_t *in, size_t len) {
177
178 uint64_t *current;
179 current = (uint64_t*)in;
180 uint64_t org_len = len;
181 uint64_t hash1 = 0;
182
183 while(len > 7) {
184 // digest words little endian first
185 hash_round(hash, le64toh(*current), 1);
186
187 current++;
188 len-=8;
189 }
190
191 // handle the rest
192 hash1 = ~hash1;
193 while(len) {
194 // byte-wise, no endianess
195 hash_round(hash, *(uint8_t*)current, 1);
196
197 current = (uint64_t*)((uint8_t*)current + 1);
198 len--;
199 }
200
201 // digest length
202 hash1 = ~hash1;
203 hash_round(hash, org_len, 1);
204
205 // caller is responsible for storing it big endian to memory (if ever)
206 return hash1;
207 }
208
209
210 uint32_t pearson_hash_32 (const uint8_t *in, size_t len) {
211
212 return pearson_hash_64(in, len);
213 }
214
215
216 uint16_t pearson_hash_16 (const uint8_t *in, size_t len) {
217
218 return pearson_hash_64(in, len);
219 }
220
221
222 void pearson_hash_init(void) {
223
224 }