Created
October 13, 2021 11:48
-
-
Save ninjachen/34f193a3c9c03c426a6be9a8a5e1c1c9 to your computer and use it in GitHub Desktop.
Murmur hash 3.0
This file contains hidden or 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