mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
79 lines
2.0 KiB
Python
79 lines
2.0 KiB
Python
# -*- 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)))
|