class KnotHash(object): def __init__(self): self.circular_list = CircularList([i for i in range(256)]) self.pos = 0 self.skip = 0 def create_hash(self, s): '''Creates a knot hash from a string of input''' # create lengths from ASCII conversions knot_lengths = [ord(c) for c in s] # append standard end lengths knot_lengths += [17, 31, 73, 47, 23] # perform ties of each lenght 64 times for i in range(64): for l in knot_lengths: self.tie(l) # reduce hash to dense hash dense_hash = self.__reduce() # create and return final string of hex values final_string = [] for n in dense_hash: h = hex(n) final_string.append(h.replace('0x', '').zfill(2)) return ''.join(final_string) def reset(self): '''Resets position and skip to 0''' self.circular_list = CircularList([i for i in range(256)]) self.pos = 0 self.skip = 0 def tie(self, length): '''Reverse portion of array for user-passed length, increases positiona and skip tracker variables''' # identify end of list end = self.pos + length # creat sub-array and reverse sub = self.circular_list.index(self.pos, end) reverse = sub[::-1] # replace all values self.circular_list.replace(self.pos, reverse) # move position self.pos = end + self.skip if self.pos > len(self.circular_list.array): self.pos %= len(self.circular_list.array) # increase skip size self.skip += 1 def __reduce(self): '''Reduces a hash to a dense hash''' # create empty list to populate with dense hash dense_hash = [] # iterate through array in groups of 16 pos = 0 while pos < len(self.circular_list.array): num = xor(self.circular_list.index(pos, pos + 16)) dense_hash.append(num) pos += 16 return dense_hash