1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2011, RedJack, LLC.
# All rights reserved.
#
# Please see the COPYING file in this distribution for license
# details.
# ----------------------------------------------------------------------
# Calculates the 32-bit MurmurHash3 hash value [1] for a string provided on the
# command line.
#
# [1] http://code.google.com/p/smhasher/wiki/MurmurHash3
def rotl32(a, b):
return (((a << (b & 0x1f)) & 0xffffffff) |
((a >> (32 - (b & 0x1f))) & 0xffffffff))
def fmix(h):
h = h ^ (h >> 16)
h = (h * 0x85ebca6b) & 0xffffffff
h = h ^ (h >> 13)
h = (h * 0xc2b2ae35) & 0xffffffff
h = h ^ (h >> 16)
return h
def hash(value, seed):
import struct
length = len(value)
num_blocks = length / 4
tail_length = length % 4
fmt = "<" + ("i" * num_blocks) + ("b" * tail_length)
vals = struct.unpack(fmt, value)
h1 = seed
c1 = 0xcc9e2d51
c2 = 0x1b873593
for block in vals[:num_blocks]:
k1 = block
k1 = (k1 * c1) & 0xffffffff
k1 = rotl32(k1, 15)
k1 = (k1 * c2) & 0xffffffff
h1 = h1 ^ k1
h1 = rotl32(h1, 13)
h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff
k1 = 0
if tail_length >= 3:
k1 = k1 ^ ((vals[num_blocks + 2] << 16) & 0xffffffff)
if tail_length >= 2:
k1 = k1 ^ ((vals[num_blocks + 1] << 8) & 0xffffffff)
if tail_length >= 1:
k1 = k1 ^ ( vals[num_blocks] & 0xffffffff)
k1 = (k1 * c1) & 0xffffffff
k1 = rotl32(k1, 15)
k1 = (k1 * c2) & 0xffffffff
h1 = h1 ^ k1
h1 = h1 ^ (length & 0xffffffff)
return fmix(h1)
if __name__ == "__main__":
import sys
if len(sys.argv) != 2 and len(sys.argv) != 3:
print("Usage: hashstring.py <string> [<seed>]")
sys.exit(1)
def myhex(v):
return hex(v).rstrip("L")
if len(sys.argv) == 3:
seed = long(sys.argv[2]) & 0xffffffff
else:
seed = 0
print(myhex(hash(sys.argv[1], seed)))
|