1

我想在没有对手的重复数据删除系统中使用 MurmurHash3。例如,Murmurhash3 将对文件进行哈希处理。

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

Murmurhash3_x86_128() (源代码)函数接收四个参数。这是我对它们的理解:

key - 要散列的输入数据

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 循环。但是,指向我的数据数组的末尾,然后它开始访问该位置之后的内存位置。解释了分段错误。所以key不能只是我的数据数组。

我的问题是:我应该在关键参数中输入什么?


问题解决了

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

4

1 回答 1

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

于 2013-01-27T20:40:15.017 回答