一.哈希函数是什么?
哈希函数,又叫散列函数、散列算法,是一种从任何一种数据中创建小的数字“指纹”(也叫做摘要)的方法。什么意思呢?就是说,你输入任何长度、任何内容的数据,哈希函数输出固定长度、固定格式的结果,这个结果类似于你输入数据的指纹。只要输入发生变化,那么指纹一定会发生变化。不同的内容,通过哈希函数得到的指纹不一样。这就是哈希函数。
Hash函数的特性
1、不定长度输入,固定长度输出:
所谓不定长度输入,固定长度输出,我们在前文中已经讲过了。就是不管输入的数据是多长,是多大,输出的数据长度、格式都是固定的。比如你选择sha256,那么你的输出就是256位。
2、抗碰撞性:
如果x不等于y,但是H(x)等于H(y),那么我们就说H()这个函数不具有抗碰撞性。反之,我们就认为其是具有抗碰撞性的。总结一句话:如果X不等Y,那么H(x)也不等于H(y),那么我们就说H()这个函数具有抗碰撞性。一个好的hash函数是一定要具有抗碰撞性的。
3:不可逆性(单项性)
给定哈希函数H()和输入数据,可以很方便的求解出哈希值,但是给定哈希值和哈希函数几乎不能求解出输入数据是什么,这就是不可逆性,也叫做单向性。
一个好的哈希函数必然具备:不定长输入固定长输出、抗碰撞性、不可逆性这三个特点。
二.Hash构造函数的方法
1.直接定址法:
直接定址法是以数据元素关键字k本身或它的线性函数作为它的哈希地址,即:H(k)=k 或 H(k)=a×k+b ; (其中a,b为常数)
例1,有一个人口统计表,记录了从1岁到100岁的人口数目,其中年龄作为关键字,哈希函数取关键字本身,当需要查找某一年龄的人数时,直接查找相应的项即可。如查找99岁的老人数,则直接读出第99项即可。如果我们要统计的是80后出生的人口数,那么我们队出生年份这个关键字可以用年份减去1980来作为地址,此时f(key)=key-1980
这种哈希函数简单,并且对于不同的关键字不会产生冲突,但可以看出这是一种较为特殊的哈希函数,实际生活中,关键字的元素很少是连续的。用该方法产生的哈希表会造成空间大量的浪费,因此这种方法适应性并不强。
此法仅适合于:地址集合的大小 = = 关键字集合的大小,其中a和b为常数。
2.数字分析法:
假设关键字集合中的每个关键字都是由 s 位数字组成 (u1, u2, …, us),分析关键字集中的全体,并从中提取分布均匀的若干位或它们的组合作为地址。