1 ## Copyright 2002-2003 Andrew Loewenstern, All Rights Reserved
2 # see LICENSE.txt for license information
4 """Functions to deal with hashes (node IDs and keys)."""
9 from twisted.trial import unittest
12 """Convert a hash (big-endian) to a long python integer."""
13 assert len(hstr) == 20
14 return long(hstr.encode('hex'), 16)
17 """Convert a long python integer to a hash."""
23 str = str.decode('hex')
24 return (20 - len(str)) *'\x00' + str
27 """Calculate the distance between two hashes expressed as strings."""
28 return intify(a) ^ intify(b)
31 """Get a new pseudorandom globally unique hash string."""
36 def newIDInRange(min, max):
37 """Get a new pseudorandom globally unique hash string in the range."""
38 return stringify(randRange(min,max))
40 def randRange(min, max):
41 """Get a new pseudorandom globally unique hash number in the range."""
42 return min + intify(newID()) % (max - min)
45 """Get a new pseudorandom transaction ID number."""
46 return randRange(-2**30, 2**30)
48 class TestNewID(unittest.TestCase):
49 """Test the newID function."""
51 self.failUnlessEqual(len(newID()), 20)
52 def testHundreds(self):
56 class TestIntify(unittest.TestCase):
57 """Test the intify function."""
58 known = [('\0' * 20, 0),
59 ('\xff' * 20, 2L**160 - 1),
62 for str, value in self.known:
63 self.failUnlessEqual(intify(str), value)
64 def testEndianessOnce(self):
66 while h[-1] == '\xff':
68 k = h[:-1] + chr(ord(h[-1]) + 1)
69 self.failUnlessEqual(intify(k) - intify(h), 1)
70 def testEndianessLots(self):
72 self.testEndianessOnce()
74 class TestDisantance(unittest.TestCase):
75 """Test the distance function."""
77 (("\0" * 20, "\xff" * 20), 2**160L -1),
78 ((sha("foo").digest(), sha("foo").digest()), 0),
79 ((sha("bar").digest(), sha("bar").digest()), 0)
82 for pair, dist in self.known:
83 self.failUnlessEqual(distance(pair[0], pair[1]), dist)
84 def testCommutitive(self):
86 x, y, z = newID(), newID(), newID()
87 self.failUnlessEqual(distance(x,y) ^ distance(y, z), distance(x, z))
89 class TestRandRange(unittest.TestCase):
90 """Test the randRange function."""
96 self.failUnlessEqual(a <= c < b, True, "output out of range %d %d %d" % (b, c, a))
99 self.failUnlessEqual(b <= c < a, True, "output out of range %d %d %d" % (b, c, a))
101 def testOneHundredTimes(self):
102 for i in xrange(100):