File: hashstring.py

package info (click to toggle)
libcork 0.15.0%2Bds-16
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,140 kB
  • sloc: ansic: 12,216; python: 206; sh: 126; makefile: 16
file content (78 lines) | stat: -rw-r--r-- 2,091 bytes parent folder | download | duplicates (4)
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)))