This is a hash produced by Bob Jenkins, and I just want to know from a more intelligent person than me if my overload method will work in all cases. It seems to be safe, but I would hate to start using it if it may fail under certain circumstances.
Code:
#include <string>
/*
Hash Author: Bob Jenkins
*/
unsigned Hash(char* pKey, unsigned pLength, unsigned pInit);
unsigned Hash(unsigned char* pKey, unsigned pLength, unsigned pInit);
unsigned Hash(const char* pKey, unsigned pInit);
unsigned Hash(std::string pKey, unsigned pInit);
unsigned Hash( char* pKey, unsigned pLength, unsigned pInit )
{
return Hash(std::string((const char*)pKey,pLength), pInit);
}
unsigned Hash( unsigned char* pKey, unsigned pLength, unsigned pInit)
{
return Hash(std::string((const char*)pKey, pLength), pInit);
}
unsigned Hash( const char *pKey, unsigned pInit )
{
return Hash(std::string(pKey),pInit);
}
void mix(unsigned& a, unsigned& b, unsigned& c)
{
a -= b; a -= c; a ^= ( c >> 13 );
b -= c; b -= a; b ^= ( a << 8 );
c -= a; c -= b; c ^= ( b >> 13 );
a -= b; a -= c; a ^= ( c >> 12 );
b -= c; b -= a; b ^= ( a << 16 );
c -= a; c -= b; c ^= ( b >> 5 );
a -= b; a -= c; a ^= ( c >> 3 );
b -= c; b -= a; b ^= ( a << 10 );
c -= a; c -= b; c ^= ( b >> 15 );
}
unsigned Hash(std::string pKey, unsigned pInit)
{
unsigned a, b;
unsigned c = pInit;
unsigned len = pKey.length();
unsigned loc = 0;
a = b = 0x9e3779b9;
while ( len >= 12 ) {
a += ( pKey[loc] + ( (unsigned)pKey[loc] << 8 )
+ ( (unsigned)pKey[loc] << 16 )
+ ( (unsigned)pKey[loc] << 24 ) );
b += ( pKey[4] + ( (unsigned)pKey[5] << 8 )
+ ( (unsigned)pKey[loc] << 16 )
+ ( (unsigned)pKey[loc] << 24 ) );
c += ( pKey[8] + ( (unsigned)pKey[9] << 8 )
+ ( (unsigned)pKey[loc] << 16 )
+ ( (unsigned)pKey[loc] << 24 ) );
mix ( a, b, c );
loc += 12;
len -= 12;
if ( loc > len )
loc = len;
}
c += pKey.length();
switch ( len ) {
case 11: c += ( (unsigned)pKey[10] << 24 );
case 10: c += ( (unsigned)pKey[9] << 16 );
case 9 : c += ( (unsigned)pKey[8] << 8 );
/* First byte of c reserved for length */
case 8 : b += ( (unsigned)pKey[7] << 24 );
case 7 : b += ( (unsigned)pKey[6] << 16 );
case 6 : b += ( (unsigned)pKey[5] << 8 );
case 5 : b += pKey[4];
case 4 : a += ( (unsigned)pKey[3] << 24 );
case 3 : a += ( (unsigned)pKey[2] << 16 );
case 2 : a += ( (unsigned)pKey[1] << 8 );
case 1 : a += pKey[0];
}
mix ( a, b, c );
return c;
}
Thank you very much for any constructive criticism.
[/SIZE][/FONT][/SIZE][/FONT]