Murmur hash 3.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rocks.ninjachen; | |
/** | |
* Murmur hash 3.0. | |
* <p> | |
* It works as the same as lastguest\Murmur in PHP in limited test data. | |
*/ | |
public final class MurmurHash { | |
/** | |
* @param key Text to hash. | |
* @param seed Positive integer only | |
* @return number 32-bit positive integer hash(No unsigned-int in Java, use Long) | |
*/ | |
public static long hash3Int(String key, int seed) { | |
byte[] bytes = key.getBytes(); | |
int klen = bytes.length; | |
long h1 = seed < 0 ? -seed : seed; // positive seed | |
int remainder = 0, i = 0; | |
long k1; | |
for (int mlen = klen - (remainder = klen & 3); i < mlen; ) { | |
k1 = bytes[i] | |
| (bytes[++i] << 8) | |
| (bytes[++i] << 16) | |
| (bytes[++i] << 24); | |
++i; | |
k1 = ((((k1 & 0xffffL) * 0xcc9e2d51) + (((((k1 >= 0 ? k1 >> 16 : ((k1 & 0x7fffffffL) >> 16) | 0x8000)) * 0xcc9e2d51) & 0xffffL) << 16))) & 0xffffffffL; | |
k1 = k1 << 15 | (k1 >= 0 ? k1 >> 17 : ((k1 & 0x7fffffffL) >> 17) | 0x4000); | |
k1 = ((((k1 & 0xffffL) * 0x1b873593) + (((((k1 >= 0 ? k1 >> 16 : ((k1 & 0x7fffffffL) >> 16) | 0x8000)) * 0x1b873593) & 0xffffL) << 16))) & 0xffffffffL; | |
h1 ^= k1; | |
h1 = h1 << 13 | (h1 >= 0 ? h1 >> 19 : ((h1 & 0x7fffffffL) >> 19) | 0x1000); | |
long h1b = ((((h1 & 0xffffL) * 5) + (((((h1 >= 0 ? h1 >> 16 : ((h1 & 0x7fffffffL) >> 16) | 0x8000)) * 5) & 0xffffL) << 16))) & 0xffffffffL; | |
h1 = (((h1b & 0xffffL) + 0x6b64) + (((((h1b >= 0 ? h1b >> 16 : ((h1b & 0x7fffffffL) >> 16) | 0x8000)) + 0xe654) & 0xffffL) << 16)); | |
} | |
k1 = 0; | |
switch (remainder) { | |
case 3: | |
k1 ^= bytes[i + 2] << 16; | |
case 2: | |
k1 ^= bytes[i + 1] << 8; | |
case 1: | |
k1 ^= bytes[i]; | |
k1 = (((k1 & 0xffffL) * 0xcc9e2d51) + (((((k1 >= 0 ? k1 >> 16 : ((k1 & 0x7fffffffL) >> 16) | 0x8000)) * 0xcc9e2d51) & 0xffffL) << 16)) & 0xffffffffL; | |
k1 = k1 << 15 | (k1 >= 0 ? k1 >> 17 : ((k1 & 0x7fffffffL) >> 17) | 0x4000); | |
k1 = (((k1 & 0xffffL) * 0x1b873593) + (((((k1 >= 0 ? k1 >> 16 : ((k1 & 0x7fffffffL) >> 16) | 0x8000)) * 0x1b873593) & 0xffffL) << 16)) & 0xffffffffL; | |
h1 ^= k1; | |
} | |
h1 ^= klen; | |
h1 ^= (h1 >= 0 ? h1 >> 16 : ((h1 & 0x7fffffffL) >> 16) | 0x8000); | |
h1 = (((h1 & 0xffffL) * 0x85ebca6b) + (((((h1 >= 0 ? h1 >> 16 : ((h1 & 0x7fffffffL) >> 16) | 0x8000)) * 0x85ebca6b) & 0xffffL) << 16)) & 0xffffffffL; | |
h1 ^= (h1 >= 0 ? h1 >> 13 : ((h1 & 0x7fffffffL) >> 13) | 0x40000); | |
h1 = ((((h1 & 0xffffL) * 0xc2b2ae35) + (((((h1 >= 0 ? h1 >> 16 : ((h1 & 0x7fffffffL) >> 16) | 0x8000)) * 0xc2b2ae35) & 0xffffL) << 16))) & 0xffffffffL; | |
h1 ^= (h1 >= 0 ? h1 >> 16 : ((h1 & 0x7fffffffL) >> 16) | 0x8000); | |
return h1; | |
} | |
public static long hash3IntModulo(String key, int divisor, int seed) { | |
return hash3Int(key, seed) % divisor; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment