2 xxHash - Fast Hash algorithm
3 Copyright (C) 2012-2016, Yann Collet
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
11 * Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following disclaimer
15 in the documentation and/or other materials provided with the
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 You can contact the author at :
31 - xxHash source repository : https://github.com/Cyan4973/xxHash
35 /* *************************************
37 ***************************************/
38 /*!XXH_FORCE_MEMORY_ACCESS
39 * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
40 * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
41 * The below switch allow to select different access method for improved performance.
42 * Method 0 (default) : use `memcpy()`. Safe and portable.
43 * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
44 * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
45 * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
46 * It can generate buggy code on targets which do not support unaligned memory accesses.
47 * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
48 * See http://stackoverflow.com/a/32095106/646947 for details.
49 * Prefer these methods in priority order (0 > 1 > 2)
51 #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
52 # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
53 # define XXH_FORCE_MEMORY_ACCESS 2
54 # elif defined(__INTEL_COMPILER) || \
55 (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
56 # define XXH_FORCE_MEMORY_ACCESS 1
60 /*!XXH_ACCEPT_NULL_INPUT_POINTER :
61 * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
62 * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
63 * By default, this option is disabled. To enable it, uncomment below define :
65 /* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */
67 /*!XXH_FORCE_NATIVE_FORMAT :
68 * By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
69 * Results are therefore identical for little-endian and big-endian CPU.
70 * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
71 * Should endian-independance be of no importance for your application, you may set the #define below to 1,
72 * to improve speed for Big-endian CPU.
73 * This option has no impact on Little_Endian CPU.
75 #define XXH_FORCE_NATIVE_FORMAT 0
77 /*!XXH_USELESS_ALIGN_BRANCH :
78 * This is a minor performance trick, only useful with lots of very small keys.
79 * It means : don't check for aligned/unaligned input, because performance will be the same.
80 * It saves one initial branch per hash.
82 #if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
83 # define XXH_USELESS_ALIGN_BRANCH 1
87 /* *************************************
88 * Compiler Specific Options
89 ***************************************/
90 #ifdef _MSC_VER /* Visual Studio */
91 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
92 # define FORCE_INLINE static __forceinline
94 # if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
96 # define FORCE_INLINE static inline __attribute__((always_inline))
98 # define FORCE_INLINE static inline
101 # define FORCE_INLINE static
102 # endif /* __STDC_VERSION__ */
106 /* *************************************
107 * Includes & Memory related functions
108 ***************************************/
109 /* Modify the local functions below should you wish to use some other memory routines */
110 /* for malloc(), free() */
112 static void* XXH_malloc(size_t s
) { return malloc(s
); }
113 static void XXH_free (void* p
) { free(p
); }
116 static void* XXH_memcpy(void* dest
, const void* src
, size_t size
) { return memcpy(dest
,src
,size
); }
121 /* *************************************
123 ***************************************/
126 # if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
128 typedef uint8_t BYTE
;
129 typedef uint16_t U16
;
130 typedef uint32_t U32
;
132 typedef uint64_t U64
;
134 typedef unsigned char BYTE
;
135 typedef unsigned short U16
;
136 typedef unsigned int U32
;
137 typedef signed int S32
;
138 typedef unsigned long long U64
;
143 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
145 /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
146 static U32
XXH_read32(const void* memPtr
) { return *(const U32
*) memPtr
; }
147 static U64
XXH_read64(const void* memPtr
) { return *(const U64
*) memPtr
; }
149 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
151 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
152 /* currently only defined for gcc and icc */
153 typedef union { U32 u32
; U64 u64
; } __attribute__((packed
)) unalign
;
155 static U32
XXH_read32(const void* ptr
) { return ((const unalign
*)ptr
)->u32
; }
156 static U64
XXH_read64(const void* ptr
) { return ((const unalign
*)ptr
)->u64
; }
160 /* portable and safe solution. Generally efficient.
161 * see : http://stackoverflow.com/a/32095106/646947
164 static U32
XXH_read32(const void* memPtr
)
167 memcpy(&val
, memPtr
, sizeof(val
));
171 static U64
XXH_read64(const void* memPtr
)
174 memcpy(&val
, memPtr
, sizeof(val
));
178 #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
181 /* ****************************************
182 * Compiler-specific Functions and Macros
183 ******************************************/
184 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
186 /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
187 #if defined(_MSC_VER)
188 # define XXH_rotl32(x,r) _rotl(x,r)
189 # define XXH_rotl64(x,r) _rotl64(x,r)
191 # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
192 # define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
195 #if defined(_MSC_VER) /* Visual Studio */
196 # define XXH_swap32 _byteswap_ulong
197 # define XXH_swap64 _byteswap_uint64
198 #elif GCC_VERSION >= 403
199 # define XXH_swap32 __builtin_bswap32
200 # define XXH_swap64 __builtin_bswap64
202 static U32
XXH_swap32 (U32 x
)
204 return ((x
<< 24) & 0xff000000 ) |
205 ((x
<< 8) & 0x00ff0000 ) |
206 ((x
>> 8) & 0x0000ff00 ) |
207 ((x
>> 24) & 0x000000ff );
209 static U64
XXH_swap64 (U64 x
)
211 return ((x
<< 56) & 0xff00000000000000ULL
) |
212 ((x
<< 40) & 0x00ff000000000000ULL
) |
213 ((x
<< 24) & 0x0000ff0000000000ULL
) |
214 ((x
<< 8) & 0x000000ff00000000ULL
) |
215 ((x
>> 8) & 0x00000000ff000000ULL
) |
216 ((x
>> 24) & 0x0000000000ff0000ULL
) |
217 ((x
>> 40) & 0x000000000000ff00ULL
) |
218 ((x
>> 56) & 0x00000000000000ffULL
);
223 /* *************************************
224 * Architecture Macros
225 ***************************************/
226 typedef enum { XXH_bigEndian
=0, XXH_littleEndian
=1 } XXH_endianess
;
228 /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
229 #ifndef XXH_CPU_LITTLE_ENDIAN
230 static const int g_one
= 1;
231 # define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one))
235 /* ***************************
237 *****************************/
238 typedef enum { XXH_aligned
, XXH_unaligned
} XXH_alignment
;
240 FORCE_INLINE U32
XXH_readLE32_align(const void* ptr
, XXH_endianess endian
, XXH_alignment align
)
242 if (align
==XXH_unaligned
)
243 return endian
==XXH_littleEndian
? XXH_read32(ptr
) : XXH_swap32(XXH_read32(ptr
));
245 return endian
==XXH_littleEndian
? *(const U32
*)ptr
: XXH_swap32(*(const U32
*)ptr
);
248 FORCE_INLINE U32
XXH_readLE32(const void* ptr
, XXH_endianess endian
)
250 return XXH_readLE32_align(ptr
, endian
, XXH_unaligned
);
253 static U32
XXH_readBE32(const void* ptr
)
255 return XXH_CPU_LITTLE_ENDIAN
? XXH_swap32(XXH_read32(ptr
)) : XXH_read32(ptr
);
258 FORCE_INLINE U64
XXH_readLE64_align(const void* ptr
, XXH_endianess endian
, XXH_alignment align
)
260 if (align
==XXH_unaligned
)
261 return endian
==XXH_littleEndian
? XXH_read64(ptr
) : XXH_swap64(XXH_read64(ptr
));
263 return endian
==XXH_littleEndian
? *(const U64
*)ptr
: XXH_swap64(*(const U64
*)ptr
);
266 FORCE_INLINE U64
XXH_readLE64(const void* ptr
, XXH_endianess endian
)
268 return XXH_readLE64_align(ptr
, endian
, XXH_unaligned
);
271 static U64
XXH_readBE64(const void* ptr
)
273 return XXH_CPU_LITTLE_ENDIAN
? XXH_swap64(XXH_read64(ptr
)) : XXH_read64(ptr
);
277 /* *************************************
279 ***************************************/
280 #define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
283 /* *************************************
285 ***************************************/
286 #define PRIME32_1 2654435761U
287 #define PRIME32_2 2246822519U
288 #define PRIME32_3 3266489917U
289 #define PRIME32_4 668265263U
290 #define PRIME32_5 374761393U
292 #define PRIME64_1 11400714785074694791ULL
293 #define PRIME64_2 14029467366897019727ULL
294 #define PRIME64_3 1609587929392839161ULL
295 #define PRIME64_4 9650029242287828579ULL
296 #define PRIME64_5 2870177450012600261ULL
298 XXH_PUBLIC_API
unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER
; }
301 /* ***************************
302 * Simple Hash Functions
303 *****************************/
304 FORCE_INLINE U32
XXH32_endian_align(const void* input
, size_t len
, U32 seed
, XXH_endianess endian
, XXH_alignment align
)
306 const BYTE
* p
= (const BYTE
*)input
;
307 const BYTE
* bEnd
= p
+ len
;
309 #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
311 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
315 bEnd
=p
=(const BYTE
*)(size_t)16;
321 const BYTE
* const limit
= bEnd
- 16;
322 U32 v1
= seed
+ PRIME32_1
+ PRIME32_2
;
323 U32 v2
= seed
+ PRIME32_2
;
325 U32 v4
= seed
- PRIME32_1
;
329 v1
+= XXH_get32bits(p
) * PRIME32_2
;
330 v1
= XXH_rotl32(v1
, 13);
333 v2
+= XXH_get32bits(p
) * PRIME32_2
;
334 v2
= XXH_rotl32(v2
, 13);
337 v3
+= XXH_get32bits(p
) * PRIME32_2
;
338 v3
= XXH_rotl32(v3
, 13);
341 v4
+= XXH_get32bits(p
) * PRIME32_2
;
342 v4
= XXH_rotl32(v4
, 13);
348 h32
= XXH_rotl32(v1
, 1) + XXH_rotl32(v2
, 7) + XXH_rotl32(v3
, 12) + XXH_rotl32(v4
, 18);
352 h32
= seed
+ PRIME32_5
;
359 h32
+= XXH_get32bits(p
) * PRIME32_3
;
360 h32
= XXH_rotl32(h32
, 17) * PRIME32_4
;
366 h32
+= (*p
) * PRIME32_5
;
367 h32
= XXH_rotl32(h32
, 11) * PRIME32_1
;
381 XXH_PUBLIC_API
unsigned int XXH32 (const void* input
, size_t len
, unsigned int seed
)
384 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
385 XXH32_CREATESTATE_STATIC(state
);
386 XXH32_reset(state
, seed
);
387 XXH32_update(state
, input
, len
);
388 return XXH32_digest(state
);
390 XXH_endianess endian_detected
= (XXH_endianess
)XXH_CPU_LITTLE_ENDIAN
;
392 # if !defined(XXH_USELESS_ALIGN_BRANCH)
393 if ((((size_t)input
) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */
395 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
396 return XXH32_endian_align(input
, len
, seed
, XXH_littleEndian
, XXH_aligned
);
398 return XXH32_endian_align(input
, len
, seed
, XXH_bigEndian
, XXH_aligned
);
402 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
403 return XXH32_endian_align(input
, len
, seed
, XXH_littleEndian
, XXH_unaligned
);
405 return XXH32_endian_align(input
, len
, seed
, XXH_bigEndian
, XXH_unaligned
);
409 FORCE_INLINE U64
XXH64_endian_align(const void* input
, size_t len
, U64 seed
, XXH_endianess endian
, XXH_alignment align
)
411 const BYTE
* p
= (const BYTE
*)input
;
412 const BYTE
* bEnd
= p
+ len
;
414 #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
416 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
420 bEnd
=p
=(const BYTE
*)(size_t)32;
426 const BYTE
* const limit
= bEnd
- 32;
427 U64 v1
= seed
+ PRIME64_1
+ PRIME64_2
;
428 U64 v2
= seed
+ PRIME64_2
;
430 U64 v4
= seed
- PRIME64_1
;
434 v1
+= XXH_get64bits(p
) * PRIME64_2
;
436 v1
= XXH_rotl64(v1
, 31);
438 v2
+= XXH_get64bits(p
) * PRIME64_2
;
440 v2
= XXH_rotl64(v2
, 31);
442 v3
+= XXH_get64bits(p
) * PRIME64_2
;
444 v3
= XXH_rotl64(v3
, 31);
446 v4
+= XXH_get64bits(p
) * PRIME64_2
;
448 v4
= XXH_rotl64(v4
, 31);
453 h64
= XXH_rotl64(v1
, 1) + XXH_rotl64(v2
, 7) + XXH_rotl64(v3
, 12) + XXH_rotl64(v4
, 18);
456 v1
= XXH_rotl64(v1
, 31);
459 h64
= h64
* PRIME64_1
+ PRIME64_4
;
462 v2
= XXH_rotl64(v2
, 31);
465 h64
= h64
* PRIME64_1
+ PRIME64_4
;
468 v3
= XXH_rotl64(v3
, 31);
471 h64
= h64
* PRIME64_1
+ PRIME64_4
;
474 v4
= XXH_rotl64(v4
, 31);
477 h64
= h64
* PRIME64_1
+ PRIME64_4
;
481 h64
= seed
+ PRIME64_5
;
488 U64 k1
= XXH_get64bits(p
);
490 k1
= XXH_rotl64(k1
,31);
493 h64
= XXH_rotl64(h64
,27) * PRIME64_1
+ PRIME64_4
;
499 h64
^= (U64
)(XXH_get32bits(p
)) * PRIME64_1
;
500 h64
= XXH_rotl64(h64
, 23) * PRIME64_2
+ PRIME64_3
;
506 h64
^= (*p
) * PRIME64_5
;
507 h64
= XXH_rotl64(h64
, 11) * PRIME64_1
;
521 XXH_PUBLIC_API
unsigned long long XXH64 (const void* input
, size_t len
, unsigned long long seed
)
524 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
525 XXH64_CREATESTATE_STATIC(state
);
526 XXH64_reset(state
, seed
);
527 XXH64_update(state
, input
, len
);
528 return XXH64_digest(state
);
530 XXH_endianess endian_detected
= (XXH_endianess
)XXH_CPU_LITTLE_ENDIAN
;
532 # if !defined(XXH_USELESS_ALIGN_BRANCH)
533 if ((((size_t)input
) & 7)==0) /* Input is aligned, let's leverage the speed advantage */
535 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
536 return XXH64_endian_align(input
, len
, seed
, XXH_littleEndian
, XXH_aligned
);
538 return XXH64_endian_align(input
, len
, seed
, XXH_bigEndian
, XXH_aligned
);
542 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
543 return XXH64_endian_align(input
, len
, seed
, XXH_littleEndian
, XXH_unaligned
);
545 return XXH64_endian_align(input
, len
, seed
, XXH_bigEndian
, XXH_unaligned
);
549 /* **************************************************
550 * Advanced Hash Functions
551 ****************************************************/
562 U32 mem32
[4]; /* defined as U32 for alignment */
564 }; /* typedef'd to XXH32_state_t within xxhash.h */
574 U64 mem64
[4]; /* defined as U64 for alignment */
576 }; /* typedef'd to XXH64_state_t within xxhash.h */
579 XXH_PUBLIC_API XXH32_state_t
* XXH32_createState(void)
581 XXH_STATIC_ASSERT(sizeof(XXH32_stateBody_t
) >= sizeof(XXH32_state_t
)); /* A compilation error here means XXH32_state_t is not large enough */
582 return (XXH32_state_t
*)XXH_malloc(sizeof(XXH32_state_t
));
584 XXH_PUBLIC_API XXH_errorcode
XXH32_freeState(XXH32_state_t
* statePtr
)
590 XXH_PUBLIC_API XXH64_state_t
* XXH64_createState(void)
592 XXH_STATIC_ASSERT(sizeof(XXH64_stateBody_t
) >= sizeof(XXH64_state_t
)); /* A compilation error here means XXH64_state_t is not large enough */
593 return (XXH64_state_t
*)XXH_malloc(sizeof(XXH64_state_t
));
595 XXH_PUBLIC_API XXH_errorcode
XXH64_freeState(XXH64_state_t
* statePtr
)
604 XXH_PUBLIC_API XXH_errorcode
XXH32_reset(XXH32_state_t
* statePtr
, unsigned int seed
)
606 XXH32_state_t state
; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
607 memset(&state
, 0, sizeof(state
));
609 state
.v1
= seed
+ PRIME32_1
+ PRIME32_2
;
610 state
.v2
= seed
+ PRIME32_2
;
612 state
.v4
= seed
- PRIME32_1
;
613 memcpy(statePtr
, &state
, sizeof(state
));
618 XXH_PUBLIC_API XXH_errorcode
XXH64_reset(XXH64_state_t
* statePtr
, unsigned long long seed
)
620 XXH64_state_t state
; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
621 memset(&state
, 0, sizeof(state
));
623 state
.v1
= seed
+ PRIME64_1
+ PRIME64_2
;
624 state
.v2
= seed
+ PRIME64_2
;
626 state
.v4
= seed
- PRIME64_1
;
627 memcpy(statePtr
, &state
, sizeof(state
));
632 FORCE_INLINE XXH_errorcode
XXH32_update_endian (XXH32_state_t
* state
, const void* input
, size_t len
, XXH_endianess endian
)
634 const BYTE
* p
= (const BYTE
*)input
;
635 const BYTE
* const bEnd
= p
+ len
;
637 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
638 if (input
==NULL
) return XXH_ERROR
;
641 state
->total_len
+= len
;
643 if (state
->memsize
+ len
< 16) /* fill in tmp buffer */
645 XXH_memcpy((BYTE
*)(state
->mem32
) + state
->memsize
, input
, len
);
646 state
->memsize
+= (U32
)len
;
650 if (state
->memsize
) /* some data left from previous update */
652 XXH_memcpy((BYTE
*)(state
->mem32
) + state
->memsize
, input
, 16-state
->memsize
);
654 const U32
* p32
= state
->mem32
;
655 state
->v1
+= XXH_readLE32(p32
, endian
) * PRIME32_2
;
656 state
->v1
= XXH_rotl32(state
->v1
, 13);
657 state
->v1
*= PRIME32_1
;
659 state
->v2
+= XXH_readLE32(p32
, endian
) * PRIME32_2
;
660 state
->v2
= XXH_rotl32(state
->v2
, 13);
661 state
->v2
*= PRIME32_1
;
663 state
->v3
+= XXH_readLE32(p32
, endian
) * PRIME32_2
;
664 state
->v3
= XXH_rotl32(state
->v3
, 13);
665 state
->v3
*= PRIME32_1
;
667 state
->v4
+= XXH_readLE32(p32
, endian
) * PRIME32_2
;
668 state
->v4
= XXH_rotl32(state
->v4
, 13);
669 state
->v4
*= PRIME32_1
;
672 p
+= 16-state
->memsize
;
678 const BYTE
* const limit
= bEnd
- 16;
686 v1
+= XXH_readLE32(p
, endian
) * PRIME32_2
;
687 v1
= XXH_rotl32(v1
, 13);
690 v2
+= XXH_readLE32(p
, endian
) * PRIME32_2
;
691 v2
= XXH_rotl32(v2
, 13);
694 v3
+= XXH_readLE32(p
, endian
) * PRIME32_2
;
695 v3
= XXH_rotl32(v3
, 13);
698 v4
+= XXH_readLE32(p
, endian
) * PRIME32_2
;
699 v4
= XXH_rotl32(v4
, 13);
713 XXH_memcpy(state
->mem32
, p
, bEnd
-p
);
714 state
->memsize
= (int)(bEnd
-p
);
720 XXH_PUBLIC_API XXH_errorcode
XXH32_update (XXH32_state_t
* state_in
, const void* input
, size_t len
)
722 XXH_endianess endian_detected
= (XXH_endianess
)XXH_CPU_LITTLE_ENDIAN
;
724 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
725 return XXH32_update_endian(state_in
, input
, len
, XXH_littleEndian
);
727 return XXH32_update_endian(state_in
, input
, len
, XXH_bigEndian
);
732 FORCE_INLINE U32
XXH32_digest_endian (const XXH32_state_t
* state
, XXH_endianess endian
)
734 const BYTE
* p
= (const BYTE
*)state
->mem32
;
735 const BYTE
* bEnd
= (const BYTE
*)(state
->mem32
) + state
->memsize
;
738 if (state
->total_len
>= 16)
740 h32
= XXH_rotl32(state
->v1
, 1) + XXH_rotl32(state
->v2
, 7) + XXH_rotl32(state
->v3
, 12) + XXH_rotl32(state
->v4
, 18);
744 h32
= state
->seed
+ PRIME32_5
;
747 h32
+= (U32
) state
->total_len
;
751 h32
+= XXH_readLE32(p
, endian
) * PRIME32_3
;
752 h32
= XXH_rotl32(h32
, 17) * PRIME32_4
;
758 h32
+= (*p
) * PRIME32_5
;
759 h32
= XXH_rotl32(h32
, 11) * PRIME32_1
;
773 XXH_PUBLIC_API
unsigned int XXH32_digest (const XXH32_state_t
* state_in
)
775 XXH_endianess endian_detected
= (XXH_endianess
)XXH_CPU_LITTLE_ENDIAN
;
777 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
778 return XXH32_digest_endian(state_in
, XXH_littleEndian
);
780 return XXH32_digest_endian(state_in
, XXH_bigEndian
);
785 /* **** XXH64 **** */
787 FORCE_INLINE XXH_errorcode
XXH64_update_endian (XXH64_state_t
* state
, const void* input
, size_t len
, XXH_endianess endian
)
789 const BYTE
* p
= (const BYTE
*)input
;
790 const BYTE
* const bEnd
= p
+ len
;
792 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
793 if (input
==NULL
) return XXH_ERROR
;
796 state
->total_len
+= len
;
798 if (state
->memsize
+ len
< 32) /* fill in tmp buffer */
800 XXH_memcpy(((BYTE
*)state
->mem64
) + state
->memsize
, input
, len
);
801 state
->memsize
+= (U32
)len
;
805 if (state
->memsize
) /* some data left from previous update */
807 XXH_memcpy(((BYTE
*)state
->mem64
) + state
->memsize
, input
, 32-state
->memsize
);
809 const U64
* p64
= state
->mem64
;
810 state
->v1
+= XXH_readLE64(p64
, endian
) * PRIME64_2
;
811 state
->v1
= XXH_rotl64(state
->v1
, 31);
812 state
->v1
*= PRIME64_1
;
814 state
->v2
+= XXH_readLE64(p64
, endian
) * PRIME64_2
;
815 state
->v2
= XXH_rotl64(state
->v2
, 31);
816 state
->v2
*= PRIME64_1
;
818 state
->v3
+= XXH_readLE64(p64
, endian
) * PRIME64_2
;
819 state
->v3
= XXH_rotl64(state
->v3
, 31);
820 state
->v3
*= PRIME64_1
;
822 state
->v4
+= XXH_readLE64(p64
, endian
) * PRIME64_2
;
823 state
->v4
= XXH_rotl64(state
->v4
, 31);
824 state
->v4
*= PRIME64_1
;
827 p
+= 32-state
->memsize
;
833 const BYTE
* const limit
= bEnd
- 32;
841 v1
+= XXH_readLE64(p
, endian
) * PRIME64_2
;
842 v1
= XXH_rotl64(v1
, 31);
845 v2
+= XXH_readLE64(p
, endian
) * PRIME64_2
;
846 v2
= XXH_rotl64(v2
, 31);
849 v3
+= XXH_readLE64(p
, endian
) * PRIME64_2
;
850 v3
= XXH_rotl64(v3
, 31);
853 v4
+= XXH_readLE64(p
, endian
) * PRIME64_2
;
854 v4
= XXH_rotl64(v4
, 31);
868 XXH_memcpy(state
->mem64
, p
, bEnd
-p
);
869 state
->memsize
= (int)(bEnd
-p
);
875 XXH_PUBLIC_API XXH_errorcode
XXH64_update (XXH64_state_t
* state_in
, const void* input
, size_t len
)
877 XXH_endianess endian_detected
= (XXH_endianess
)XXH_CPU_LITTLE_ENDIAN
;
879 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
880 return XXH64_update_endian(state_in
, input
, len
, XXH_littleEndian
);
882 return XXH64_update_endian(state_in
, input
, len
, XXH_bigEndian
);
887 FORCE_INLINE U64
XXH64_digest_endian (const XXH64_state_t
* state
, XXH_endianess endian
)
889 const BYTE
* p
= (const BYTE
*)state
->mem64
;
890 const BYTE
* bEnd
= (const BYTE
*)state
->mem64
+ state
->memsize
;
893 if (state
->total_len
>= 32)
900 h64
= XXH_rotl64(v1
, 1) + XXH_rotl64(v2
, 7) + XXH_rotl64(v3
, 12) + XXH_rotl64(v4
, 18);
903 v1
= XXH_rotl64(v1
, 31);
906 h64
= h64
*PRIME64_1
+ PRIME64_4
;
909 v2
= XXH_rotl64(v2
, 31);
912 h64
= h64
*PRIME64_1
+ PRIME64_4
;
915 v3
= XXH_rotl64(v3
, 31);
918 h64
= h64
*PRIME64_1
+ PRIME64_4
;
921 v4
= XXH_rotl64(v4
, 31);
924 h64
= h64
*PRIME64_1
+ PRIME64_4
;
928 h64
= state
->seed
+ PRIME64_5
;
931 h64
+= (U64
) state
->total_len
;
935 U64 k1
= XXH_readLE64(p
, endian
);
937 k1
= XXH_rotl64(k1
,31);
940 h64
= XXH_rotl64(h64
,27) * PRIME64_1
+ PRIME64_4
;
946 h64
^= (U64
)(XXH_readLE32(p
, endian
)) * PRIME64_1
;
947 h64
= XXH_rotl64(h64
, 23) * PRIME64_2
+ PRIME64_3
;
953 h64
^= (*p
) * PRIME64_5
;
954 h64
= XXH_rotl64(h64
, 11) * PRIME64_1
;
968 XXH_PUBLIC_API
unsigned long long XXH64_digest (const XXH64_state_t
* state_in
)
970 XXH_endianess endian_detected
= (XXH_endianess
)XXH_CPU_LITTLE_ENDIAN
;
972 if ((endian_detected
==XXH_littleEndian
) || XXH_FORCE_NATIVE_FORMAT
)
973 return XXH64_digest_endian(state_in
, XXH_littleEndian
);
975 return XXH64_digest_endian(state_in
, XXH_bigEndian
);
979 /* **************************
980 * Canonical representation
981 ****************************/
983 /*! Default XXH result types are basic unsigned 32 and 64 bits.
984 * The canonical representation follows human-readable write convention, aka big-endian (large digits first).
985 * These functions allow transformation of hash result into and from its canonical format.
986 * This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
989 XXH_PUBLIC_API
void XXH32_canonicalFromHash(XXH32_canonical_t
* dst
, XXH32_hash_t hash
)
991 XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t
) == sizeof(XXH32_hash_t
));
992 if (XXH_CPU_LITTLE_ENDIAN
) hash
= XXH_swap32(hash
);
993 memcpy(dst
, &hash
, sizeof(*dst
));
996 XXH_PUBLIC_API
void XXH64_canonicalFromHash(XXH64_canonical_t
* dst
, XXH64_hash_t hash
)
998 XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t
) == sizeof(XXH64_hash_t
));
999 if (XXH_CPU_LITTLE_ENDIAN
) hash
= XXH_swap64(hash
);
1000 memcpy(dst
, &hash
, sizeof(*dst
));
1003 XXH_PUBLIC_API XXH32_hash_t
XXH32_hashFromCanonical(const XXH32_canonical_t
* src
)
1005 return XXH_readBE32(src
);
1008 XXH_PUBLIC_API XXH64_hash_t
XXH64_hashFromCanonical(const XXH64_canonical_t
* src
)
1010 return XXH_readBE64(src
);