-
Notifications
You must be signed in to change notification settings - Fork 0
/
comp_hash.py
64 lines (53 loc) · 1.62 KB
/
comp_hash.py
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
"""
Experimenting with a composable hash for a rope class.
What I need is for different orders of concatenations of different flats to not affect the hash value.
Requirements: h((a . b) . c) == h(a . (b . c))
Preferred: h(a . b) != h(b . a)
Options: define h(expr) = f(g(expr), len(expr)), so that the length further hashes the result
"""
def test(f, g, h):
a = "What I need is for different "
b = "orders of concatenations of different flats "
c = "to not affect the hash value."
ab = a + b
bc = b + c
abc = a + b + c
f_a = f(a)
f_b = f(b)
f_c = f(c)
f_ab = f(ab)
f_bc = f(bc)
f_abc = f(abc)
g_fa_fbc = g(f_a, f_bc)
g_fab_fc = g(f_ab, f_c)
h_fabc = h(f_abc, len(abc))
h_a_bc = h(g_fa_fbc, len(abc))
h_ab_c = h(g_fab_fc, len(abc))
return """f(a) = %x
f(b) = %x
f(c) = %x
f(ab) = %x
f(bc) = %x
f(abc) = %x
g(f(a), f(bc)) = %x
g(f(ab), f(c)) = %x
h(f(abc)) = %x
h(g(f(a), f(bc)) = %x
h(g(f(ab), f(c)) = %x""" % (f_a, f_b, f_c, f_ab, f_bc, f_abc,
g_fa_fbc, g_fab_fc, h_fabc, h_a_bc,
h_ab_c)
bound = (1 << 32) - 5
mask = (1 << 32) - 1
def flat(string):
x = 1
for char in string:
x = (x * (2 + ord(char))) % bound
return x
def mult(hash_a, hash_b):
return (hash_a * hash_b) % bound
def blorg(num, base=1627):
""" Takes a value and gets something very large to xor against. """
return pow(base, num, bound)
def final(num, length):
return (num ^ blorg(length + 4)) & mask
print(test(flat, mult, final))