Permalink
Browse files

Added test files for a composable hash.

  • Loading branch information...
1 parent b7f410e commit cae96070e015608b359cc3c8a2a9541ce000bd1b @scooby committed Jun 16, 2012
Showing with 86 additions and 0 deletions.
  1. +64 −0 python/comp_hash.py
  2. BIN python/exp_dist.ods
  3. +22 −0 python/powtest.py
View
@@ -0,0 +1,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))
View
Binary file not shown.
View
@@ -0,0 +1,22 @@
+""" Test how evenly distributed a base is over many values.
+
+Pushing them into bins, a simple linear regression finds no
+bias. Should probably do a chi^2 test.
+"""
+
+base = 1627
+top = 1 << 32
+
+bins = 1024
+vals = [0 for _ in range(0, bins)]
+
+num = 655360
+for p in range(num):
+ vals[pow(base, p, top) >> 22] += 1
+
+count = sum(vals)
+assert count == num
+avg = count / bins
+
+for i, c in enumerate(vals):
+ print("%d\t%d\t%d" % (i, c - avg, c))

0 comments on commit cae9607

Please sign in to comment.