首先明确几点:
1.unsigned int为4个字节32位
2.异或操作中0是单位元,任何数与1异或相当于取反
3.unsigned无符号类型的数据右移操作均是执行逻辑右移(左高位自动补0)
4.ELFhash算法的核心在于“影响“
先附上代码:
unsigned int ELFhash(char *str)
{
unsigned int hash=0;
unsigned int x=0;
while(*str)
{
hash=(hash<<4)+*str; //1
if((x=hash & 0xf0000000)!=0) //2
{
hash^=(x>>24); //影响5-8位,杂糅一次 3
hash&=~x; //清空高四位 4
}
str++; //5
}
return (hash & 0x7fffffff); //6
}
int ELFHash(char *key) { unsigned long h=0; while(*key) { h=(h<<4)+(*key++); unsigned long g=h&0Xf0000000L; if(g) h^=g>>24; h&=~g; } return h%M; }
解释:
首先我们的hash结果是一个unsigned int类型的数据:
0000 0000 0000 0000
1.hash左移4位,将str插入(一个char有八位)第一次杂糅(故意这么做使之混乱)需要注意标记一下,我们在第一个字节的高四位做了第一次杂糅。
2.x这里用0xf0000000(十六进制下f为15 即1111)获取了hash的第四个字节的高四位,并用高四位作为掩码做第二次杂糅
在这里我们首先声明一下,因为我们的ELFhash强调的是每个字符都要对最后的结构有影响,所以说我们左移到一定程度是会吞掉最高的四位的,所以说我们要将最高的四位先对串产生影响,再让他被吞掉,之后的所有的影响都是叠加的,这就是多次的杂糅保证散列均匀,防止出现冲突的大量出现
3.x掩码右移24位移动到刚才的5-8位 再对5-8位进行第二次杂糅
4.定时清空高四位,实际上没有必要,但是算法要求,因为我们下一次的左移会自动吞掉这四位(是否会减少我们的hash的范围?)
5.str递增,引入下一个字符进行杂糅
6.返回一个缺失了最高符号位的无符号数(为了之后防止用到了有符号的时候造成的溢出)作为最后的hash值
————————————————
版权声明:本文修改自CSDN博主「GMFTBY」的原创文章。
原文链接:https://blog.csdn.net/ltyqljhwcm/article/details/52966874
来源:CSDN
作者:captain_shuri
链接:https://blog.csdn.net/captain_shuri/article/details/104779017