#include <stdio.h>
#include <ctype.h> //多谢citylove指正。
//crytTable[]里面保存的是HashString函数里面将会用到的一些数据,在prepareCryptTable
//函数里面初始化
unsigned long cryptTable[0x500];
//以下的函数生成一个长度为0x500(合10进制数:1280)的cryptTable[0x500]
void prepareCryptTable()
{
unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;
for( index1 = 0; index1 < 0x100; index1++ )
{
for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )
{
unsigned long temp1, temp2;
seed = (seed * 125 + 3) % 0x2AAAAB;
temp1 = (seed & 0xFFFF) << 0x10;
seed = (seed * 125 + 3) % 0x2AAAAB;
temp2 = (seed & 0xFFFF);
cryptTable[index2] = ( temp1 | temp2 );
}
}
}
//以下函数计算lpszFileName 字符串的hash值,其中dwHashType 为hash的类型,
//在下面GetHashTablePos函数里面调用本函数,其可以取的值为0、1、2;该函数
//返回lpszFileName 字符串的hash值;
unsigned long HashString( char *lpszFileName, unsigned long dwHashType )
{
unsigned char *key = (unsigned char *)lpszFileName;
unsigned long seed1 = 0x7FED7FED;
unsigned long seed2 = 0xEEEEEEEE;
int ch;
while( *key != 0 )
{
ch = toupper(*key++);
seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
}
return seed1;
}
//在main中测试argv[1]的三个hash值:
//./hash "arr/units.dat"
//./hash "unit/neutral/acritter.grp"
int main( int argc, char **argv )
{
unsigned long ulHashValue;
int i = 0;
if ( argc != 2 )
{
printf("please input two arguments/n");
return -1;
}
/*初始化数组:crytTable[0x500]*/
prepareCryptTable();
/*打印数组crytTable[0x500]里面的值*/
for ( ; i < 0x500; i++ )
{
if ( i % 10 == 0 )
{
printf("/n");
}
printf("%-12X", cryptTable[i] );
}
ulHashValue = HashString( argv[1], 0 );
printf("/n--%X --/n", ulHashValue );
ulHashValue = HashString( argv[1], 1 );
printf("--%X --/n", ulHashValue );
ulHashValue = HashString( argv[1], 2 );
printf("--%X --/n", ulHashValue );
return 0;
}
从网上看到这个很经典的Hash算法,但是有几点没有明白:
1. prepareCryptTable和HashString函数中构造cryptTable、Hash值时这些参数和公式是怎么选择出来的呢?例如:seed = 0x00100001,seed = (seed * 125 + 3) % 0x2AAAAB;
这里又是怎么样保证构造的cryptTable表中没有重复呢?
2. 这个Hash算法中的冲突率是怎么计算来的呢?
解决方案
20
冲突率就可以简单理解成重复率吧
重复率从原理上说,假如结果为1字节,那么当输入数据超过256种时,必然产生重复。
当输入数据小于256时,也有可能产生重复,这与算法设计有关,真正的算法是由数学证明过的,不是拍脑门想出来的。
重复率从原理上说,假如结果为1字节,那么当输入数据超过256种时,必然产生重复。
当输入数据小于256时,也有可能产生重复,这与算法设计有关,真正的算法是由数学证明过的,不是拍脑门想出来的。
40
hash的计算应该尽量避免重复,但过程也不要太复杂,否则效率也未必会提高