是否有任何已知的哈希算法输入int的向量并输出一个与内积相似的int?
换句话说,我正在考虑在C ++中可能看起来像这样的哈希算法:
// For simplicity, I'm not worrying about overflow, and assuming |v| < 7.
int HashVector(const vector<int>& v) {
const int N = kSomethingBig;
const int w[] = {234, 739, 934, 23, 828, 194}; // Carefully chosen constants.
int result = 0;
for (int i = 0; i < v.size(); ++i) result = (result + w[i] * v[i]) % N;
return result;
}
我对此感兴趣,因为我正在撰写一篇关于算法的论文,该算法将受益于之前关于类似哈希的任何工作。特别是,如果知道像这样的散列算法的碰撞属性,那将会很棒。
我感兴趣的算法会散列整数向量,但浮点向量的东西也会很酷。
澄清
哈希旨在用于哈希表中以进行快速键/值查找。这里没有安全问题。
所需的答案类似于一组常量,这些常量对于像这样的散列特别有用 - 类似于乘法器和模数,它比其他常量数字生成器更好。
例如,已知线性同余伪随机发生器的一些常数选择可提供最佳周期长度并具有易于计算的模数。也许有人做过研究,表明在向量散列中有一组乘法常数和模数常量可以减少邻近整数向量之间碰撞的几率。
答案 0 :(得分:3)
我做了一些(未发布的,实用的)实验,测试了各种字符串哈希算法。 (事实证明,Java的Strings默认哈希函数很糟糕。)
简单的实验是对英语词典进行哈希,并比较算法A与算法B的碰撞次数。
您可以构建一个类似的实验:随机生成长度为7或更短的$ BIG_NUMBER个可能的向量。在算法A上哈希,在算法B上哈希,然后比较冲突的数量和严重程度。
在你能够做到这一点之后,你可以使用模拟退火或类似的技术找到适合你的“魔术数字”。在我的工作中,对于给定的感兴趣的词汇表和严格限制的散列大小,我们能够通过改变“魔术数字”使通用算法适用于几种人类语言。
答案 1 :(得分:2)
根据常量的大小,我不得不说输入向量中的混沌程度会对结果产生影响。但是,对您的帖子进行快速定性分析会表明您有一个良好的开端:
出于好奇,为什么不使用现有的哈希算法进行整数并对结果进行一些有趣的数学运算呢?
答案 2 :(得分:1)
Python用于以这种方式散列元组(source):
class tuple:
def __hash__(self):
value = 0x345678
for item in self:
value = c_mul(1000003, value) ^ hash(item)
value = value ^ len(self)
if value == -1:
value = -2
return value
在您的情况下,item
将始终是一个整数,它使用此算法:
class int:
def __hash__(self):
value = self
if value == -1:
value == -2
return value
这确实与内在产品无关,但是......所以也许它没什么帮助。
答案 3 :(得分:0)