我面临与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位整数。
有人有任何建议吗?
答案 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位,因此您必须在某处丢弃数据。这只是丢弃哪些比特,以及你如何做到这一点。