Я хочу использовать MurmurHash3 в системе дедупликации без противника. Так, например, Murmurhash3 будет хэшировать файлы.
Однако у меня проблемы с его использованием, то есть я делаю что-то не так.
Murmurhash3_x86_128 () (исходный код) Функция получает четыре параметра. Это мое понимание того, что они:
ключ — ввод данных в хеш
Len — длина данных
семя — семя
из — вычисленное значение хеша
При запуске происходит сбой с ошибками сегментации из-за этой части кода:
void MurmurHash3_x86_128 ( const void * key, const uint32_t len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const uint32_t nblocks = len / 16;
...
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
for(i = -nblocks; i; i++)
{
uint32_t k1 = blocks[i*4];
...
}
...
}
Так что, если мои данные имеют длину более 15 байтов (это так), это для цикла выполнен. Тем не мение, блоки указывает на конец моего массива данных, а затем он начинает доступ к позициям памяти после этой позиции. Ошибки сегментации объяснены. Так ключ не может быть просто мой массив данных.
Мой вопрос: что я должен положить в ключ параметр?
Задача решена
После ответа Матса Петерссона я понял, что в моем коде есть ошибка. Я должен быть int (подписано), и у меня было это без знака. Вот почему это было добавление позиций памяти в блоки, а не вычитание.
blocks
указывает на последнее четное число, кратное 16 байтам в вычисляемом блоке.
i
начинается с -nblocks и всегда меньше нуля (цикл заканчивается на нуле).
Итак, скажем, у вас есть 64 байта данных, а затем указатель blocks
будет указывать на data + 64
байты и nblocks
будет 4
,
КОГДА мы добираемся до k1 = blocks[i*4];
первый раз, i = -4
так мы получили индекс -16
— который умножается на sizeof(*blocks)
это 4 (int = 4 байта в большинстве архитектур) — так что мы получаем -64
= начальный адрес data
,
Других решений пока нет …