diff --git a/wyhash.h b/wyhash.h index 7df33d4..bdbb18d 100644 --- a/wyhash.h +++ b/wyhash.h @@ -10,6 +10,7 @@ #ifndef wyhash_final_version_4 #define wyhash_final_version_4 +// Version 4.1 #ifndef WYHASH_CONDOM //protections that produce different results: @@ -113,6 +114,72 @@ static inline uint64_t _wyr4(const uint8_t *p) { return (((v >> 24) & 0xff)| ((v >> 8) & 0xff00)| ((v << 8) & 0xff0000)| ((v << 24) & 0xff000000)); } #endif +#if WYHASH_CONDOM +// must be sorted +static const uint32_t wyhash32low_badseeds[] += { 0x138d5f9f, 0x1e4f8661, 0x29362732, 0x49a7ee03, + 0x4d29ced1, 0x5ee3628c, 0x833f0eb6, 0x928fce63, + 0x99be0ae5, 0xac470842, 0xcaf21e71, 0xfc1c4878 }; +//static const uint32_t wyhash_badseeds[] = { }; + +# if defined __cplusplus +// fixup bad seeds with WYHASH_CONDOM +static inline void wyhash_seed_init(uint32_t &seed) { + return; + /*for (auto s : wyhash_badseeds) { + if (s == seed) { + seed++; + return; + } + if (s > seed) + return; + }*/ +} +static inline void wyhash_seed_init(uint64_t &seed) { + return; + /*for (auto s : wyhash_badseeds) { + if (s & seed) { + seed++; + return; + } + }*/ +} +static void wyhash32low_seed_init(uint32_t &seed) { + // just linear search for now + for (auto s : wyhash32low_badseeds) { + if (s == seed) { + seed++; + return; + } + if (s > seed) + return; + } +} +# else +// check bad seeds with WYHASH_CONDOM +static inline bool wyhash_badseed(const uint64_t seed) { + /*for (auto s : wyhash_badseeds) { + if (s & seed) { + return true; + } + }*/ + return false; +} +static bool wyhash32low_badseed(const uint32_t seed) { + // just linear search for now + for (auto s : wyhash32low_badseeds) { + if (s == seed) { + return true; + } + if (s > seed) + return false; + } + return false; +} +# endif +#endif // WYHASH_CONDOM + + static inline uint64_t _wyr3(const uint8_t *p, size_t k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];} //wyhash main function static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const uint64_t *secret){ diff --git a/wyhash32.h b/wyhash32.h index 877ad55..3211735 100644 --- a/wyhash32.h +++ b/wyhash32.h @@ -1,4 +1,5 @@ // Author: Wang Yi +// Version 4.1 #include #include #ifndef WYHASH32_BIG_ENDIAN @@ -14,8 +15,21 @@ static inline void _wymix32(unsigned *A, unsigned *B){ *A=(unsigned)c; *B=(unsigned)(c>>32); } -// This version is vulnerable when used with a few bad seeds, which should be skipped beforehand: -// 0x429dacdd, 0xd637dbf3 +// This version is vulnerable when used with a few bad seeds, which should be +// skipped or changed beforehand: 0x51a43a0f, 0x522235ae, 0x99ac2b20 +#ifdef __cplusplus +static void wyhash32_seed_init(uint32_t &seed) { + if ((seed == 0x51a43a0f) || (seed == 0x522235ae) || (seed == 0x99ac2b20)) + seed++; +} +#else +static bool wyhash32_badseed(const uint32_t seed) { + if ((seed == 0x51a43a0f) || (seed == 0x522235ae) || (seed == 0x99ac2b20)) + return true; + return false; +} +#endif + static inline unsigned wyhash32(const void *key, uint64_t len, unsigned seed) { const uint8_t *p=(const uint8_t *)key; uint64_t i=len; unsigned see1=(unsigned)len; seed^=(unsigned)(len>>32); _wymix32(&seed, &see1);