Hash 应用一个复杂的散列函数,然后取mod n,而不是简单地对输入执行mod n,有什么好处?

Hash 应用一个复杂的散列函数,然后取mod n,而不是简单地对输入执行mod n,有什么好处?,hash,hashmap,hashtable,hashcode,Hash,Hashmap,Hashtable,Hashcode,在散列中,我们接受输入并应用一些复杂的散列算法。然后,我们使用mod n查找需要将此输入发送到的bucket或服务器。 散列输入x->Hash(x)->除以n->Hash(x)mod n给出存储桶的位置 如果我们直接获取输入而不进行散列,则相当于拥有一个标识散列函数。散列(x)=x。。mod n..Wikipedia将此函数称为“普通”哈希函数 通常,散列(x)是一种复杂的散列算法,如MD5、SHA等。。。 Q1)不管我们如何散列它,它只是归结为一个介于0和n-1之间的值(当除以n时)。那么,哈

在散列中,我们接受输入并应用一些复杂的散列算法。然后,我们使用mod n查找需要将此输入发送到的bucket或服务器。 散列输入x->Hash(x)->除以n->Hash(x)mod n给出存储桶的位置

如果我们直接获取输入而不进行散列,则相当于拥有一个标识散列函数。散列(x)=x。。mod n..Wikipedia将此函数称为“普通”哈希函数

通常,散列(x)是一种复杂的散列算法,如MD5、SHA等。。。 Q1)不管我们如何散列它,它只是归结为一个介于0和n-1之间的值(当除以n时)。那么,哈希函数的选择有什么关系呢? 问题2)我知道理想的散列函数将输入值均匀地分布在各个存储桶中。在这方面,那些复杂的散列函数是否优于散列标识函数

假设输入总是一个整数

应用一个复杂的散列函数,然后取mod n,而不是简单地对输入执行mod n,有什么好处

让我们看一个简单的例子。假设我们的键是指向内存中某些8字节对齐的对象的100个指针:这意味着3个最低有效位总是0。我们的表大小目前为128个桶。在散列之前,我们将指针值修改为128,我们有效地采用:

 32-bit pointer bits   xxxxxxxx xxxxxxxx xxxxxxxx xxxxx000
             mod 128   00000000 00000000 00000000 0xxxx000
请注意,指针中只有4个潜在有意义的位可以传递到哈希函数,这意味着最多有16个不同的值到达哈希函数:我们的100个指针将只碰撞到16个存储桶,这意味着即使对于最强的哈希函数,碰撞链也通常为7或8深。这是可悲的,因为我们有128个存储桶来存储100个密钥:我们应该将大部分0、1或2个密钥映射到任何给定的存储桶

现在,如果我们有100个指向内存映射区域的指针,每个4096字节的页面对齐,会发生什么?它们都会映射到同一个bucket

在结束之前不执行mod操作可确保键中的高阶位有助于随机化散列值中的低阶位位置,而这些低阶位会影响键映射到的存储桶。另一个可以帮助的是确保表大小是素数,但是最好是在散列后进行mod。作为随机抽样,GNU的C++编译器使用标准桶哈希表来对标准库哈希表进行使用,而Visual C++使用两个幂(长字符串更快但哈希函数较弱))< /P> Q1)不管我们如何散列它,它只是归结为一个介于0和n-1之间的值(当除以n时)。那么,哈希函数的选择有什么关系呢

显然,如果我们的散列函数是
h(key){return0}
,那么每个key都会在bucket 0处发生冲突。在另一个极端,crytographic散列函数应该有效地随机但重复地将任何给定的密钥映射到给定的bucket,这样,密钥中任何位置的任何更改都会创建一个完全不相关的映射。这有助于保护您免受与在许多位位置上不会变化的键的过度碰撞。但是,强散列函数往往需要更长的计算时间,冲突的减少可能会或可能不会导致净性能的提高。有时,根据键之间的差异程度来选择哈希函数的强度是值得的

问题2)我知道理想的散列函数将输入值均匀地分布在各个存储桶中。在这方面,那些复杂的散列函数是否优于散列标识函数

在极端情况下,标识散列函数希望输入数字映射到不同的存储桶上的概率比结晶强度散列函数更高:例如,如果我们使用标识函数将5、6、7、8、10散列到一个表中,它们是密集的(彼此接近),并且只跨越6个值(5到10),因此,只要表大小>=6(例如素数值7),它们就保证不会发生冲突。但是,给定容易发生冲突的输入(例如,指向数字的指针)的标识散列函数是一场灾难,因为在mod启动之前,它们没有做任何事情来混合高有效位和低有效位,这与上面针对指针解释的问题相同


概括地说,标识哈希函数对于普通整数键具有更好的平均情况性能,但对于非密集、非随机/易冲突的键,其最坏情况性能要差得多。

什么是“哈希标识函数”,至少与您的问题相关?顺便说一句…我同意你在问题中提到的所有其他内容。在数学中,一个返回输入值作为输出的函数称为恒等式函数…f(x)=x。是的,复杂的散列函数(例如加密函数)比使用更简单的函数要好,假设前者确实以更均匀的方式进行桶输入。如果他们这样做了,他们就更优秀了。这是显而易见的。我的问题是——他们会这么做吗?这个假设正确吗?如果不是,那么那些复杂的散列算法将是一种过分的杀伤力。对于密码学来说,散列函数是按照非常苛刻的标准设计的。对于散列表,散列函数的设计可以很好地分配输入,并且计算速度非常快。加密哈希函数对于哈希表应用程序来说无疑是杀伤力过大,而为哈希表设计的哈希函数对于加密目的来说将是无望的弱。Q1)………是8字节对齐的:这意味着3个最低有效位始终是0”-始终是0。你能解释一下吗?Q2)模块128-00000000 00000000 00000000 0xxxx000。。只有四位变化?mod 128除以128表示提醒。所以,它表示0到127之间的任何值。所有这些数字如何表示