1 ## Copyright 2002 Andrew Loewenstern, All Rights Reserved
4 from whrandom import randrange
6 ## takes a 20 bit hash, big-endian, and returns it expressed a python integer
7 ## ha ha ha ha if this were a C module I wouldn't resort to such sillyness
9 assert(len(hstr) == 20)
12 i = i + ord(hstr[18]) * 256L
13 i = i + ord(hstr[17]) * 65536L
14 i = i + ord(hstr[16]) * 16777216L
15 i = i + ord(hstr[15]) * 4294967296L
16 i = i + ord(hstr[14]) * 1099511627776L
17 i = i + ord(hstr[13]) * 281474976710656L
18 i = i + ord(hstr[12]) * 72057594037927936L
19 i = i + ord(hstr[11]) * 18446744073709551616L
20 i = i + ord(hstr[10]) * 4722366482869645213696L
21 i = i + ord(hstr[9]) * 1208925819614629174706176L
22 i = i + ord(hstr[8]) * 309485009821345068724781056L
23 i = i + ord(hstr[7]) * 79228162514264337593543950336L
24 i = i + ord(hstr[6]) * 20282409603651670423947251286016L
25 i = i + ord(hstr[5]) * 5192296858534827628530496329220096L
26 i = i + ord(hstr[4]) * 1329227995784915872903807060280344576L
27 i = i + ord(hstr[3]) * 340282366920938463463374607431768211456L
28 i = i + ord(hstr[2]) * 87112285931760246646623899502532662132736L
29 i = i + ord(hstr[1]) * 22300745198530623141535718272648361505980416L
30 i = i + ord(hstr[0]) * 5708990770823839524233143877797980545530986496L
33 ## returns the distance between two 160-bit hashes expressed as 20-character strings
35 return intify(a) ^ intify(b)
38 ## returns a new pseudorandom globally unique ID string
42 h.update(chr(randrange(0,256)))
45 def randRange(min, max):
46 return min + intify(newID()) % (max - min)
50 class NewID(unittest.TestCase):
52 self.assertEqual(len(newID()), 20)
53 def testHundreds(self):
57 class Intify(unittest.TestCase):
58 known = [('\0' * 20, 0),
59 ('\xff' * 20, 2L**160 - 1),
62 for str, value in self.known:
63 self.assertEqual(intify(str), value)
64 def testEndianessOnce(self):
66 while h[-1] == '\xff':
68 k = h[:-1] + chr(ord(h[-1]) + 1)
69 self.assertEqual(intify(k) - intify(h), 1)
70 def testEndianessLots(self):
72 self.testEndianessOnce()
74 class Disantance(unittest.TestCase):
76 (("\0" * 20, "\xff" * 20), 2**160L -1),
77 ((sha("foo").digest(), sha("foo").digest()), 0),
78 ((sha("bar").digest(), sha("bar").digest()), 0)
81 for pair, dist in self.known:
82 self.assertEqual(distance(pair[0], pair[1]), dist)
83 def testCommutitive(self):
85 x, y, z = newID(), newID(), newID()
86 self.assertEqual(distance(x,y) ^ distance(y, z), distance(x, z))
88 class RandRange(unittest.TestCase):
94 self.assertEqual(a <= c < b, 1, "output out of range %d %d %d" % (b, c, a))
97 assert b <= c < a, "output out of range %d %d %d" % (b, c, a)
99 def testOneHundredTimes(self):
100 for i in xrange(100):
105 if __name__ == '__main__':