digest-xxhash 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +61 -0
- data/Rakefile +20 -0
- data/digest-xxhash.gemspec +29 -0
- data/ext/digest/xxhash/debug-funcs.h +46 -0
- data/ext/digest/xxhash/ext.c +771 -0
- data/ext/digest/xxhash/extconf.rb +2 -0
- data/ext/digest/xxhash/utils.h +151 -0
- data/ext/digest/xxhash/xxhash.c +888 -0
- data/ext/digest/xxhash/xxhash.h +293 -0
- data/lib/digest/xxhash/version.rb +5 -0
- data/test/produce-vectors-with-ruby-xxhash.rb +73 -0
- data/test/test.rb +85 -0
- data/test/test.vectors +462 -0
- metadata +105 -0
@@ -0,0 +1,293 @@
|
|
1
|
+
/*
|
2
|
+
xxHash - Extremely Fast Hash algorithm
|
3
|
+
Header File
|
4
|
+
Copyright (C) 2012-2016, Yann Collet.
|
5
|
+
|
6
|
+
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
7
|
+
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
9
|
+
modification, are permitted provided that the following conditions are
|
10
|
+
met:
|
11
|
+
|
12
|
+
* Redistributions of source code must retain the above copyright
|
13
|
+
notice, this list of conditions and the following disclaimer.
|
14
|
+
* Redistributions in binary form must reproduce the above
|
15
|
+
copyright notice, this list of conditions and the following disclaimer
|
16
|
+
in the documentation and/or other materials provided with the
|
17
|
+
distribution.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
25
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
27
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
You can contact the author at :
|
32
|
+
- xxHash source repository : https://github.com/Cyan4973/xxHash
|
33
|
+
*/
|
34
|
+
|
35
|
+
/* Notice extracted from xxHash homepage :
|
36
|
+
|
37
|
+
xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
|
38
|
+
It also successfully passes all tests from the SMHasher suite.
|
39
|
+
|
40
|
+
Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
|
41
|
+
|
42
|
+
Name Speed Q.Score Author
|
43
|
+
xxHash 5.4 GB/s 10
|
44
|
+
CrapWow 3.2 GB/s 2 Andrew
|
45
|
+
MumurHash 3a 2.7 GB/s 10 Austin Appleby
|
46
|
+
SpookyHash 2.0 GB/s 10 Bob Jenkins
|
47
|
+
SBox 1.4 GB/s 9 Bret Mulvey
|
48
|
+
Lookup3 1.2 GB/s 9 Bob Jenkins
|
49
|
+
SuperFastHash 1.2 GB/s 1 Paul Hsieh
|
50
|
+
CityHash64 1.05 GB/s 10 Pike & Alakuijala
|
51
|
+
FNV 0.55 GB/s 5 Fowler, Noll, Vo
|
52
|
+
CRC32 0.43 GB/s 9
|
53
|
+
MD5-32 0.33 GB/s 10 Ronald L. Rivest
|
54
|
+
SHA1-32 0.28 GB/s 10
|
55
|
+
|
56
|
+
Q.Score is a measure of quality of the hash function.
|
57
|
+
It depends on successfully passing SMHasher test set.
|
58
|
+
10 is a perfect score.
|
59
|
+
|
60
|
+
A 64-bits version, named XXH64, is available since r35.
|
61
|
+
It offers much better speed, but for 64-bits applications only.
|
62
|
+
Name Speed on 64 bits Speed on 32 bits
|
63
|
+
XXH64 13.8 GB/s 1.9 GB/s
|
64
|
+
XXH32 6.8 GB/s 6.0 GB/s
|
65
|
+
*/
|
66
|
+
|
67
|
+
#ifndef XXHASH_H_5627135585666179
|
68
|
+
#define XXHASH_H_5627135585666179 1
|
69
|
+
|
70
|
+
#if defined (__cplusplus)
|
71
|
+
extern "C" {
|
72
|
+
#endif
|
73
|
+
|
74
|
+
|
75
|
+
/* ****************************
|
76
|
+
* Definitions
|
77
|
+
******************************/
|
78
|
+
#include <stddef.h> /* size_t */
|
79
|
+
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
|
80
|
+
|
81
|
+
|
82
|
+
/* ****************************
|
83
|
+
* API modifier
|
84
|
+
******************************/
|
85
|
+
/** XXH_PRIVATE_API
|
86
|
+
* This is useful to include xxhash functions in `static` mode
|
87
|
+
* in order to inline them, and remove their symbol from the public list.
|
88
|
+
* Methodology :
|
89
|
+
* #define XXH_PRIVATE_API
|
90
|
+
* #include "xxhash.h"
|
91
|
+
* `xxhash.c` is automatically included.
|
92
|
+
* It's not useful to compile and link it as a separate module.
|
93
|
+
*/
|
94
|
+
#ifdef XXH_PRIVATE_API
|
95
|
+
# ifndef XXH_STATIC_LINKING_ONLY
|
96
|
+
# define XXH_STATIC_LINKING_ONLY
|
97
|
+
# endif
|
98
|
+
# if defined(__GNUC__)
|
99
|
+
# define XXH_PUBLIC_API static __inline __attribute__((unused))
|
100
|
+
# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
101
|
+
# define XXH_PUBLIC_API static inline
|
102
|
+
# elif defined(_MSC_VER)
|
103
|
+
# define XXH_PUBLIC_API static __inline
|
104
|
+
# else
|
105
|
+
# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
106
|
+
# endif
|
107
|
+
#else
|
108
|
+
# define XXH_PUBLIC_API /* do nothing */
|
109
|
+
#endif /* XXH_PRIVATE_API */
|
110
|
+
|
111
|
+
/*!XXH_NAMESPACE, aka Namespace Emulation :
|
112
|
+
|
113
|
+
If you want to include _and expose_ xxHash functions from within your own library,
|
114
|
+
but also want to avoid symbol collisions with other libraries which may also include xxHash,
|
115
|
+
|
116
|
+
you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
|
117
|
+
with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values).
|
118
|
+
|
119
|
+
Note that no change is required within the calling program as long as it includes `xxhash.h` :
|
120
|
+
regular symbol name will be automatically translated by this header.
|
121
|
+
*/
|
122
|
+
#ifdef XXH_NAMESPACE
|
123
|
+
# define XXH_CAT(A,B) A##B
|
124
|
+
# define XXH_NAME2(A,B) XXH_CAT(A,B)
|
125
|
+
# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
|
126
|
+
# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
|
127
|
+
# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
|
128
|
+
# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
|
129
|
+
# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
|
130
|
+
# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
|
131
|
+
# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
|
132
|
+
# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
|
133
|
+
# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
|
134
|
+
# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
|
135
|
+
# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
|
136
|
+
# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
|
137
|
+
# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
|
138
|
+
# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
|
139
|
+
# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
|
140
|
+
# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
|
141
|
+
# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
|
142
|
+
# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
|
143
|
+
# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
|
144
|
+
#endif
|
145
|
+
|
146
|
+
|
147
|
+
/* *************************************
|
148
|
+
* Version
|
149
|
+
***************************************/
|
150
|
+
#define XXH_VERSION_MAJOR 0
|
151
|
+
#define XXH_VERSION_MINOR 6
|
152
|
+
#define XXH_VERSION_RELEASE 2
|
153
|
+
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
|
154
|
+
XXH_PUBLIC_API unsigned XXH_versionNumber (void);
|
155
|
+
|
156
|
+
|
157
|
+
/*-**********************************************************************
|
158
|
+
* 32-bits hash
|
159
|
+
************************************************************************/
|
160
|
+
typedef unsigned int XXH32_hash_t;
|
161
|
+
|
162
|
+
/*! XXH32() :
|
163
|
+
Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
|
164
|
+
The memory between input & input+length must be valid (allocated and read-accessible).
|
165
|
+
"seed" can be used to alter the result predictably.
|
166
|
+
Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */
|
167
|
+
XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
|
168
|
+
|
169
|
+
/*====== Streaming ======*/
|
170
|
+
typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
|
171
|
+
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
|
172
|
+
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
|
173
|
+
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
|
174
|
+
|
175
|
+
XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
|
176
|
+
XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
|
177
|
+
XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
|
178
|
+
|
179
|
+
/*
|
180
|
+
These functions generate the xxHash of an input provided in multiple segments.
|
181
|
+
Note that, for small input, they are slower than single-call functions, due to state management.
|
182
|
+
For small input, prefer `XXH32()` and `XXH64()` .
|
183
|
+
|
184
|
+
XXH state must first be allocated, using XXH*_createState() .
|
185
|
+
|
186
|
+
Start a new hash by initializing state with a seed, using XXH*_reset().
|
187
|
+
|
188
|
+
Then, feed the hash state by calling XXH*_update() as many times as necessary.
|
189
|
+
Obviously, input must be allocated and read accessible.
|
190
|
+
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
|
191
|
+
|
192
|
+
Finally, a hash value can be produced anytime, by using XXH*_digest().
|
193
|
+
This function returns the nn-bits hash as an int or long long.
|
194
|
+
|
195
|
+
It's still possible to continue inserting input into the hash state after a digest,
|
196
|
+
and generate some new hashes later on, by calling again XXH*_digest().
|
197
|
+
|
198
|
+
When done, free XXH state space if it was allocated dynamically.
|
199
|
+
*/
|
200
|
+
|
201
|
+
/*====== Canonical representation ======*/
|
202
|
+
|
203
|
+
typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
|
204
|
+
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
|
205
|
+
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
|
206
|
+
|
207
|
+
/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
|
208
|
+
* The canonical representation uses human-readable write convention, aka big-endian (large digits first).
|
209
|
+
* These functions allow transformation of hash result into and from its canonical format.
|
210
|
+
* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
|
211
|
+
*/
|
212
|
+
|
213
|
+
|
214
|
+
#ifndef XXH_NO_LONG_LONG
|
215
|
+
/*-**********************************************************************
|
216
|
+
* 64-bits hash
|
217
|
+
************************************************************************/
|
218
|
+
typedef unsigned long long XXH64_hash_t;
|
219
|
+
|
220
|
+
/*! XXH64() :
|
221
|
+
Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
|
222
|
+
"seed" can be used to alter the result predictably.
|
223
|
+
This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
|
224
|
+
*/
|
225
|
+
XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
|
226
|
+
|
227
|
+
/*====== Streaming ======*/
|
228
|
+
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
|
229
|
+
XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
|
230
|
+
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
|
231
|
+
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
|
232
|
+
|
233
|
+
XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
|
234
|
+
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
|
235
|
+
XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
|
236
|
+
|
237
|
+
/*====== Canonical representation ======*/
|
238
|
+
typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
|
239
|
+
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
|
240
|
+
XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
|
241
|
+
#endif /* XXH_NO_LONG_LONG */
|
242
|
+
|
243
|
+
|
244
|
+
#ifdef XXH_STATIC_LINKING_ONLY
|
245
|
+
|
246
|
+
/* ================================================================================================
|
247
|
+
This section contains definitions which are not guaranteed to remain stable.
|
248
|
+
They may change in future versions, becoming incompatible with a different version of the library.
|
249
|
+
They shall only be used with static linking.
|
250
|
+
Never use these definitions in association with dynamic linking !
|
251
|
+
=================================================================================================== */
|
252
|
+
|
253
|
+
/* These definitions are only meant to make possible
|
254
|
+
static allocation of XXH state, on stack or in a struct for example.
|
255
|
+
Never use members directly. */
|
256
|
+
|
257
|
+
struct XXH32_state_s {
|
258
|
+
unsigned total_len_32;
|
259
|
+
unsigned large_len;
|
260
|
+
unsigned v1;
|
261
|
+
unsigned v2;
|
262
|
+
unsigned v3;
|
263
|
+
unsigned v4;
|
264
|
+
unsigned mem32[4]; /* buffer defined as U32 for alignment */
|
265
|
+
unsigned memsize;
|
266
|
+
unsigned reserved; /* never read nor write, will be removed in a future version */
|
267
|
+
}; /* typedef'd to XXH32_state_t */
|
268
|
+
|
269
|
+
#ifndef XXH_NO_LONG_LONG /* remove 64-bits support */
|
270
|
+
struct XXH64_state_s {
|
271
|
+
unsigned long long total_len;
|
272
|
+
unsigned long long v1;
|
273
|
+
unsigned long long v2;
|
274
|
+
unsigned long long v3;
|
275
|
+
unsigned long long v4;
|
276
|
+
unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
|
277
|
+
unsigned memsize;
|
278
|
+
unsigned reserved[2]; /* never read nor write, will be removed in a future version */
|
279
|
+
}; /* typedef'd to XXH64_state_t */
|
280
|
+
#endif
|
281
|
+
|
282
|
+
#ifdef XXH_PRIVATE_API
|
283
|
+
# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */
|
284
|
+
#endif
|
285
|
+
|
286
|
+
#endif /* XXH_STATIC_LINKING_ONLY */
|
287
|
+
|
288
|
+
|
289
|
+
#if defined (__cplusplus)
|
290
|
+
}
|
291
|
+
#endif
|
292
|
+
|
293
|
+
#endif /* XXHASH_H_5627135585666179 */
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-xxhash'
|
4
|
+
|
5
|
+
rijndael_sbox = [
|
6
|
+
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
7
|
+
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
8
|
+
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
9
|
+
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
10
|
+
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
11
|
+
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
12
|
+
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
13
|
+
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
14
|
+
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
15
|
+
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
16
|
+
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
17
|
+
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
18
|
+
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
19
|
+
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
20
|
+
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
21
|
+
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
22
|
+
]
|
23
|
+
|
24
|
+
_32bit_seeds = rijndael_sbox.each_slice(4).map{ |e| e.map{ |f| "%02x" % f }.join }.to_a
|
25
|
+
_32bit_seeds_cycles = _32bit_seeds.cycle.each_slice(32)
|
26
|
+
_64bit_seeds = rijndael_sbox.each_slice(8).map{ |e| e.map{ |f| "%02x" % f }.join }.to_a
|
27
|
+
|
28
|
+
def get_repeated_0x00_to_0xff(length)
|
29
|
+
hex = (0..0xff).to_a.map{ |e| sprintf "%2x", e }.join
|
30
|
+
str = [hex].pack('H*')
|
31
|
+
cycles = (Float(length) / str.size).ceil
|
32
|
+
[str].cycle(cycles).to_a.join[0...length]
|
33
|
+
end
|
34
|
+
|
35
|
+
[
|
36
|
+
[32, 'null', 0],
|
37
|
+
[32, '0x00_to_0xff', 17 ** 0],
|
38
|
+
[32, '0x00_to_0xff', 17 ** 1],
|
39
|
+
[32, '0x00_to_0xff', 17 ** 2],
|
40
|
+
[32, '0x00_to_0xff', 17 ** 3],
|
41
|
+
[32, '0x00_to_0xff', 17 ** 4],
|
42
|
+
[32, '0x00_to_0xff', 17 ** 5],
|
43
|
+
[64, 'null', 0],
|
44
|
+
[64, '0x00_to_0xff', 17 ** 0],
|
45
|
+
[64, '0x00_to_0xff', 17 ** 1],
|
46
|
+
[64, '0x00_to_0xff', 17 ** 2],
|
47
|
+
[64, '0x00_to_0xff', 17 ** 3],
|
48
|
+
[64, '0x00_to_0xff', 17 ** 4],
|
49
|
+
[64, '0x00_to_0xff', 17 ** 5]
|
50
|
+
].each do |bit_size, msg_method, msg_length|
|
51
|
+
case msg_method
|
52
|
+
when 'null'
|
53
|
+
msg = ''
|
54
|
+
when '0x00_to_0xff'
|
55
|
+
msg = get_repeated_0x00_to_0xff(msg_length)
|
56
|
+
else
|
57
|
+
raise "Invalid message generation method."
|
58
|
+
end
|
59
|
+
|
60
|
+
if bit_size == 32
|
61
|
+
["00000000"].concat(_32bit_seeds_cycles.next).each do |seed|
|
62
|
+
sum = XXhash.xxh32(msg, seed.to_i(16))
|
63
|
+
$stdout.puts "#{bit_size}|#{msg_method}|#{msg_length}|#{seed}|#{"%08x" % sum}"
|
64
|
+
$stdout.flush
|
65
|
+
end
|
66
|
+
else
|
67
|
+
["0000000000000000"].concat(_64bit_seeds).each do |seed|
|
68
|
+
sum = XXhash.xxh64(msg, seed.to_i(16))
|
69
|
+
$stdout.puts "#{bit_size}|#{msg_method}|#{msg_length}|#{seed}|#{"%016x" % sum}"
|
70
|
+
$stdout.flush
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/test/test.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
# To show more verbose messages, install minitest-reporters and uncomment the
|
5
|
+
# following lines:
|
6
|
+
#
|
7
|
+
# require "minitest/reporters"
|
8
|
+
# Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
|
9
|
+
|
10
|
+
TEST_DIR = File.dirname(__FILE__)
|
11
|
+
require File.join(TEST_DIR, %w{ .. lib digest xxhash })
|
12
|
+
|
13
|
+
def get_repeated_0x00_to_0xff(length)
|
14
|
+
hex = (0..0xff).to_a.map{ |e| sprintf "%2x", e }.join
|
15
|
+
str = [hex].pack('H*')
|
16
|
+
cycles = (Float(length) / str.size).ceil
|
17
|
+
[str].cycle(cycles).to_a.join[0...length]
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Digest::XXH32 do
|
21
|
+
it "produces correct types of digest outputs" do
|
22
|
+
Digest::XXH32.digest("").must_be_instance_of String
|
23
|
+
Digest::XXH32.hexdigest("").must_be_instance_of String
|
24
|
+
Digest::XXH32.idigest("").must_be_instance_of Fixnum
|
25
|
+
Digest::XXH32.new.digest("").must_be_instance_of String
|
26
|
+
Digest::XXH32.new.hexdigest("").must_be_instance_of String
|
27
|
+
Digest::XXH32.new.idigest("").must_be_instance_of Fixnum
|
28
|
+
end
|
29
|
+
|
30
|
+
it "produces similar output with its digest, hexdigest and idigest methods" do
|
31
|
+
digest = Digest::XXH32.digest("abcd")
|
32
|
+
Digest::XXH32.new.digest("abcd").must_equal digest
|
33
|
+
Digest::XXH32.new.update("ab").update("cd").digest.must_equal digest
|
34
|
+
Digest::XXH32.new.update("ab").update("cd").digest!.must_equal digest
|
35
|
+
Digest::XXH32.new.reset.update("ab").update("cd").digest!.must_equal digest
|
36
|
+
|
37
|
+
hexdigest = Digest::XXH32.hexdigest("abcd")
|
38
|
+
Digest::XXH32.new.hexdigest("abcd").must_equal hexdigest
|
39
|
+
Digest::XXH32.new.update("ab").update("cd").hexdigest.must_equal hexdigest
|
40
|
+
Digest::XXH32.new.update("ab").update("cd").hexdigest!.must_equal hexdigest
|
41
|
+
Digest::XXH32.new.reset.update("ab").update("cd").hexdigest!.must_equal hexdigest
|
42
|
+
|
43
|
+
idigest = Digest::XXH32.idigest("abcd")
|
44
|
+
Digest::XXH32.new.idigest("abcd").must_equal idigest
|
45
|
+
Digest::XXH32.new.update("ab").update("cd").idigest.must_equal idigest
|
46
|
+
Digest::XXH32.new.update("ab").update("cd").idigest!.must_equal idigest
|
47
|
+
Digest::XXH32.new.reset.update("ab").update("cd").idigest!.must_equal idigest
|
48
|
+
|
49
|
+
digest_enc = digest.unpack('H*').pop
|
50
|
+
hexdigest.must_equal digest_enc
|
51
|
+
|
52
|
+
idigest_enc = "%08x" % idigest
|
53
|
+
hexdigest.must_equal idigest_enc
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
CSV.foreach(File.join(TEST_DIR, 'test.vectors'), col_sep: '|').with_index(1) do |csv, line_num|
|
58
|
+
bit_size, msg_method, msg_length, seed, sum = csv
|
59
|
+
|
60
|
+
case msg_method
|
61
|
+
when 'null'
|
62
|
+
msg = ''
|
63
|
+
when '0x00_to_0xff'
|
64
|
+
msg = get_repeated_0x00_to_0xff(msg_length.to_i)
|
65
|
+
else
|
66
|
+
raise "Invalid specified message generation method in 'test.vectors', line #{line_num}."
|
67
|
+
end
|
68
|
+
|
69
|
+
case bit_size.to_i
|
70
|
+
when 32
|
71
|
+
klass = Digest::XXH32
|
72
|
+
when 64
|
73
|
+
klass = Digest::XXH64
|
74
|
+
else
|
75
|
+
raise "Invalid specified bit size in 'test.vectors', line #{line_num}."
|
76
|
+
end
|
77
|
+
|
78
|
+
describe klass do
|
79
|
+
describe "using #{msg_method}(#{msg_length}) as message generator, and #{seed} as seed" do
|
80
|
+
it "should produce #{sum}" do
|
81
|
+
klass.hexdigest(msg, seed).must_equal sum
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|