使用几个uint32_t整数生成uint64_t哈希键

时间:2010-06-25 12:07:39

标签: c++ algorithm optimization

我面临与Eduardo(Generate a hash sum for several integers)相同的问题,但我的标题中有一点不同。

我有四个32位整数,我需要生成一个64位唯一键。我现在所做的是生成由'/'分隔的四周整数的字符串连接,然后用字符串生成CRC。

char id_s[64];
sprintf(id_s, "%d/%d/%d/%d", a, b, c, d);
uint64_t id = CRC(id_s);

但问题是我必须完成数百万次,因此它看起来非常耗费CPU。所以我在考虑直接将四个整数存储到一个整数中。

如果16位整数的四个整数,这可以很容易地完成。它可以使用位移运算符来完成。

uint64_t id = a << 48 + b << 32 + c << 16 + d;

有四个32位整数,我必须将128位放入一个64位整数。

有人有任何建议吗?

2 个答案:

答案 0 :(得分:2)

我认为你最好的选择是使用xor:

  uint64_t makeId(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
  {
     uint64_t id = a;
     id <<=11;
     id ^= b;
     id <<=11;
     id ^= c;
     id <<=10;
     id ^=d;

     return id;
  }

如果您的输入分布均匀且使用全部32位,这将非常有效。就像马克所说,如果没有重复,就无法将128位变成64位。

答案 1 :(得分:1)

根据输入数据的性质,几乎像您建议的那样可能正常工作:

uint64_t id = static_cast<uint64_t>(a & 0xFFFFu) << 48 + static_cast<uint64_t>(b & 0xFFFFu) << 32 + static_cast<uint64_t>(c & 0xFFFFu) << 16 + static_cast<uint64_t>(d & 0xFFFFu);

只要值的高位相当恒定而低位相对随机,这应该让你接近。您试图将128位数据塞入64位,因此您必须在某处丢弃数据。这只是丢弃哪些比特,以及你如何做到这一点。