Смотри, этот класс использует хэш из библиотеки. Помоги мне аккуратно переписать код таким образом, чтобы я смог использовать свой код для создания хэшей. Вот класс:

class ConsistentHashing:
    def __init__(self):
        self.ring = {}
        self.sorted_keys = []

    def _hash(self, key):
        # Хэширует ключ и возвращает его значение
        hash_value = int(hashlib.md5(key.encode()).hexdigest(), 16)
        print(f"Хэш для ключа '{key}': {hash_value}")
        return hash_value

    def add_node(self, node):
        node_hash = self._hash(node)
        if node_hash not in self.ring:
            self.ring[node_hash] = node
            self.sorted_keys.append(node_hash)
            self.sorted_keys.sort()
            print(f"Добавлен узел '{node}' с хэшем {node_hash} на кольцо.")
            print(f"Текущее состояние кольца: {self.ring}")
        else:
            print(f"Узел '{node}' уже существует.")

    def remove_node(self, node):
        node_hash = self._hash(node)
        if node_hash in self.ring:
            del self.ring[node_hash]
            self.sorted_keys.remove(node_hash)
            print(f"Удален узел '{node}' с хэшем {node_hash} из кольца.")
            print(f"Текущее состояние кольца: {self.ring}")
        else:
            print(f"Узел '{node}' не найден.")

    def get_node(self, key):
        if not self.ring:
            print("Кольцо пустое, узлы не найдены.")
            return None

        key_hash = self._hash(key)

        # Поиск ближайшего узла
        for ring_key in self.sorted_keys:
            if key_hash <= ring_key:
                print(f"Ключ '{key}' (хэш {key_hash}) обрабатывается узлом '{self.ring[ring_key]}'.")
                return self.ring[ring_key]

        next_node = self.ring[self.sorted_keys[0]]
        print(f"Ключ '{key}' (хэш {key_hash}) обрабатывается узлом '{next_node}' (первая позиция на кольце).")
        return next_node

А вот мой способ генерации хэшей:
def generate_matrix_and_vector(n, m=32):
    A = np.random.randint(0, 2, size=(n, m), dtype=np.int8)
    b = np.random.randint(0, 2, size=n, dtype=np.int8)
    return A, b

def generate_hash(A, b, x):

  # error handling
  n, m = A.shape
  if m != 32:
        raise ValueError("Matrix A must have 32 columns.")
  if len(b) != n:
        raise ValueError("Vector b must have the same number of elements as rows in matrix A.")

  # x to binary
  x = int(x)
  x_bits = np.array([(x >> i) & 1 for i in range(32)], dtype=np.int8)

  # r
  r = np.zeros(n, dtype=np.int8)
  for i in range(n):
    Ai = A[i]
    logic_AND_result = Ai & x_bits
    #print("A[i]:\n", Ai)
    #print("x:\n", x_bits)
    #print("A[i] & x:\n", logic_AND_result, "\nnumber of 1:\t", np.sum(logic_AND_result))

    # evenness counting (number of '1')
    parity = np.sum(logic_AND_result) % 2
    #print("parity:\t", parity)

    r[i] = parity  # parity -> i-th bit of r[]
    #print("r[i]:\t", r[i], "\n")

  # r XOR b
  logic_XOR_result = r ^ b
  #print("r:\n", r)
  #print("b:\n", b, "\n")

  return logic_XOR_result

# Параметры хеш-функции
A, b = generate_matrix_and_vector(16)
# Сгенерировать поток данных
x = generate_data('uniform', 100000)
# Посчитать хэш-значения
hashed_values = [generate_hash(A, b, x_value) for x_value in x]