/** * Third version of the MurmurHash hashing function, * returns a 32 bit unsigned integer. */ u32 murmur3(char *s) { u32 c1 = 0xcc9e2d51; u32 c2 = 0x1b873593; u32 r1 = 15; u32 r2 = 13; u32 m = 5; u32 n = 0xe6546b64; u32 hash = SEED; u32 len = strlen(s); int nblocks = len / 4; u32 *blocks = (u32 *) s; u32 k; for (int i = 0; i < nblocks; i++) { k = blocks[i]; k *= c1; k = ROTATE32(k, r1); k *= c2; hash ^= k; hash = ROTATE32(hash, r2) * m + n; } u32 *tail = (u32 *) (s + nblocks * 4); u32 k1 = 0; switch (len & 3) { case 3: k1 ^= tail[2] << 16; case 2: k1 ^= tail[1] << 8; case 1: k1 ^= tail[0]; k1 *= c1; k1 = ROTATE32(k1, r1); k1 *= c2; hash ^= k1; } hash ^= len; hash ^= (hash >> 16); hash *= 0x85ebca6b; hash ^= (hash >> 13); hash *= 0xc2b2ae35; hash ^= (hash >> 16); return hash; }
void inline ws_mask(char *buf, int len, unsigned int mask) { char *p = buf; char *end = buf + len; /* xor first bits, until aligned */ for (; p < end && (((unsigned long)p) % sizeof(unsigned long *)); p++, mask = ROTATE32(mask)) *p ^= MASK8(mask); /* xor the big chunk, which is aligned */ for (; p < end - (sizeof(int) - 1); p += sizeof(int)) *((int *)p) ^= mask; /* the last chunk may not be processed */ for (; p < end; p++, mask >>= 8) *p ^= MASK8(mask); //ws_print_masked(buf, len); }