diff options
author | Yves Orton <demerphq@gmail.com> | 2012-12-10 08:36:43 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2013-03-19 00:23:11 +0100 |
commit | b1300a738fa7f7665aa35a1f9347cf71c52a5b6e (patch) | |
tree | 557ece3739433518cfb786e53cfe3445caef2b0d /hv_func.h | |
parent | 4d3a042da1832ef30203f1ded27917696c9d86a9 (diff) | |
download | perl-b1300a738fa7f7665aa35a1f9347cf71c52a5b6e.tar.gz |
add a hardened one-at-a-time hash variant
Mix in additional randomness into the final value.
Diffstat (limited to 'hv_func.h')
-rw-r--r-- | hv_func.h | 49 |
1 files changed, 46 insertions, 3 deletions
@@ -18,12 +18,13 @@ || defined(PERL_HASH_FUNC_SUPERFAST) \ || defined(PERL_HASH_FUNC_MURMUR3) \ || defined(PERL_HASH_FUNC_ONE_AT_A_TIME) \ + || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) \ || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_OLD) \ ) #ifdef HAS_QUAD #define PERL_HASH_FUNC_SIPHASH #else -#define PERL_HASH_FUNC_ONE_AT_A_TIME +#define PERL_HASH_FUNC_ONE_AT_A_TIME_HARD #endif #endif @@ -47,6 +48,10 @@ # define PERL_HASH_FUNC "SDBM" # define PERL_HASH_SEED_BYTES 4 # define PERL_HASH(hash,str,len) (hash)= S_perl_hash_sdbm(PERL_HASH_SEED,(U8*)(str),(len)) +#elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) +# define PERL_HASH_FUNC "ONE_AT_A_TIME_HARD" +# define PERL_HASH_SEED_BYTES 8 +# define PERL_HASH(hash,str,len) (hash)= S_perl_hash_one_at_a_time_hard(PERL_HASH_SEED,(U8*)(str),(len)) #elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME) # define PERL_HASH_FUNC "ONE_AT_A_TIME" # define PERL_HASH_SEED_BYTES 4 @@ -460,9 +465,11 @@ S_perl_hash_sdbm(const unsigned char * const seed, const unsigned char *str, con } -/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins +/* This is the "One-at-a-Time" algorithm by Bob Jenkins * from requirements by Colin Plumb. - * (http://burtleburtle.net/bob/hash/doobs.html) */ + * (http://burtleburtle.net/bob/hash/doobs.html) + * With seed/len tweak. + * */ PERL_STATIC_INLINE U32 S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) { const unsigned char * const end = (const unsigned char *)str + len; @@ -477,6 +484,42 @@ S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char return (hash + (hash << 15)); } +/* Derived from "One-at-a-Time" algorithm by Bob Jenkins */ +PERL_STATIC_INLINE U32 +S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned char *str, const STRLEN len) { + const unsigned char * const end = (const unsigned char *)str + len; + U32 hash = *((U32*)seed) + len; + + while (str < end) { + hash += (hash << 10); + hash ^= (hash >> 6); + hash += *str++; + } + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[4]; + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[5]; + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[6]; + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[7]; + + hash += (hash << 10); + hash ^= (hash >> 6); + + hash += (hash << 3); + hash ^= (hash >> 11); + return (hash + (hash << 15)); +} + PERL_STATIC_INLINE U32 S_perl_hash_old_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) { const unsigned char * const end = (const unsigned char *)str + len; |