Murmurhash3_x86_128如何处理大于15字节的数据?

时间:2013-01-27 20:28:40

标签: c++ c hash murmurhash

我想在没有对手的重复数据删除系统中使用MurmurHash3。例如,Murmurhash3会散列文件。

但是我在使用它时遇到了问题,这意味着我做错了什么。

Murmurhash3_x86_128()(source-code)函数接收四个参数。这是我对它们的理解:

- 输入数据到哈希

len - 数据长度

种子 - 种子

out - 计算哈希值

当运行它失败并出现分段错误时,由于代码的这一部分:

    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个字节(在这种情况下),则执行 for loop 。但是, blocks 指向我的数据数组的末尾,然后它开始访问该位置之后的内存位置。解释了分段错误。所以 key 不能仅仅是我的数据阵列。

我的问题是:我应该在参数中添加什么内容?


解决了问题

在Mats Petersson的回答之后,我意识到我的代码有一个错误。我必须是一个int(签名),我没有签名。这就是它为块添加内存位置而不是减去的原因。

1 个答案:

答案 0 :(得分:1)

blocks指向正在计算的块中最后一个16字节的倍数。

i从-nblocks开始,始终小于零(循环结束于零)。

因此,假设您有64个字节的数据,那么指针blocks将指向data + 64个字节,nblocks将指向4

我们第一次到达k1 = blocks[i*4];i = -4,所以得到索引-16 - 乘以sizeof(*blocks),即4(int = 4大多数架构中的字节数) - 所以我们得到-64 = data的起始地址。