Robert Jenkin's hash function

        哈希表是一种常用的数据结构。它们包括一个数组(哈希表)和映射(哈希函数)。哈希函数把关键码值映射到表中一个位置。存储在哈希表中的数据必须有对应的键。哈希函数将一个项的键映射到一个哈希值,并且该哈希值被用作该项的一个索引到该项的哈希表中。这使得数据能够快速访问。

                                                          哈希算法的模型

 initialize the internal state;
  for (each block of the input)
  {
    combine (the internal state, the current input block);
    mix( the internal state);
  }
  value = postprocess( the internal state );
  return (value);

例如XORhash:

  char XORhash( char *key, int len)
  {
    char hash;
    int  i;
    for (hash=0, i=0; i<len; ++i) hash=hash^key[i];
    return (hash%101);           /* 101 is prime */
  }

                                                             32位哈希
<pre>typedef  unsigned long int  u4;   /* unsigned 4-byte type */
typedef  unsigned     char  u1;   /* unsigned 1-byte type */

/* The mixing step */
#define mix(a,b,c) \
{ \
  a=a-b;  a=a-c;  a=a^(c>>13); \
  b=b-c;  b=b-a;  b=b^(a<<8);  \
  c=c-a;  c=c-b;  c=c^(b>>13); \
  a=a-b;  a=a-c;  a=a^(c>>12); \
  b=b-c;  b=b-a;  b=b^(a<<16); \
  c=c-a;  c=c-b;  c=c^(b>>5);  \
  a=a-b;  a=a-c;  a=a^(c>>3);  \
  b=b-c;  b=b-a;  b=b^(a<<10); \
  c=c-a;  c=c-b;  c=c^(b>>15); \
}

/* The whole new hash function */
u4 hash( k, length, initval)
register u1 *k;        /* the key */
u4           length;   /* the length of the key in bytes */
u4           initval;  /* the previous hash, or an arbitrary value */
{
   register u4 a,b,c;  /* the internal state */
   u4          len;    /* how many key bytes still need mixing */

   /* Set up the internal state */
   len = length;
   a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
   c = initval;         /* variable initialization of internal state */

   /*---------------------------------------- handle most of the key */
   while (len >= 12)
   {
      a=a+(k[0]+((u4)k[1]<<8)+((u4)k[2]<<16) +((u4)k[3]<<24));
      b=b+(k[4]+((u4)k[5]<<8)+((u4)k[6]<<16) +((u4)k[7]<<24));
      c=c+(k[8]+((u4)k[9]<<8)+((u4)k[10]<<16)+((u4)k[11]<<24));
      mix(a,b,c);
      k = k+12; len = len-12;
   }

   /*------------------------------------- handle the last 11 bytes */
   c = c+length;
   switch(len)              /* all the case statements fall through */
   {
   case 11: c=c+((u4)k[10]<<24);
   case 10: c=c+((u4)k[9]<<16);
   case 9 : c=c+((u4)k[8]<<8);
      /* the first byte of c is reserved for the length */
   case 8 : b=b+((u4)k[7]<<24);
   case 7 : b=b+((u4)k[6]<<16);
   case 6 : b=b+((u4)k[5]<<8);
   case 5 : b=b+k[4];
   case 4 : a=a+((u4)k[3]<<24);
   case 3 : a=a+((u4)k[2]<<16);
   case 2 : a=a+((u4)k[1]<<8);
   case 1 : a=a+k[0];
     /* case 0: nothing left to add */
   }
   mix(a,b,c);
   /*-------------------------------------------- report the result */
   return c;
}

 
The new hash deals with blocks of 12 bytes, rather than 1 byte at a time like most hashes.The whole hash, including the mix, takes about 6m+35 instructions to hash m bytes 

                                                              64位哈希
<pre>#define mix64(a,b,c) \
{ \
  a=a-b;  a=a-c;  a=a^(c>>43); \
  b=b-c;  b=b-a;  b=b^(a<<9); \
  c=c-a;  c=c-b;  c=c^(b>>8); \
  a=a-b;  a=a-c;  a=a^(c>>38); \
  b=b-c;  b=b-a;  b=b^(a<<23); \
  c=c-a;  c=c-b;  c=c^(b>>5); \
  a=a-b;  a=a-c;  a=a^(c>>35); \
  b=b-c;  b=b-a;  b=b^(a<<49); \
  c=c-a;  c=c-b;  c=c^(b>>11); \
  a=a-b;  a=a-c;  a=a^(c>>12); \
  b=b-c;  b=b-a;  b=b^(a<<18); \
  c=c-a;  c=c-b;  c=c^(b>>22); \
}

 
The whole 64-bit hash takes about 5 
m 
+41 instructions to hash  
m 
 bytes. 


细究慢慢看英文吧。

http://burtleburtle.net/bob/hash/evahash.html



Jenkins Hash 是由 Bob Jenkins 设计的一种哈希算法,它可以将任意长度的输入数据映射为一个 32 位的哈希值。Jenkins Hash 的实现非常简单,具有良好的散列性和高效性,被广泛应用于各种编程语言中。 Jenkins Hash 的核心思想是将输入数据分成若干个 4 字节的块,对每个块进行一系列简单的位运算和乘法运算,最后将结果累加起来得到哈希值。具体来说,Jenkins Hash 的伪代码如下: ``` uint32_t jenkins_hash(const void* key, size_t length, uint32_t initval) { uint32_t a, b, c, len; const uint8_t* data = (const uint8_t*)key; len = length; a = b = 0x9e3779b9; c = initval; while (len >= 12) { a += (data[0] + ((uint32_t)data[1] << 8) + ((uint32_t)data[2] << 16) + ((uint32_t)data[3] << 24)); b += (data[4] + ((uint32_t)data[5] << 8) + ((uint32_t)data[6] << 16) + ((uint32_t)data[7] << 24)); c += (data[8] + ((uint32_t)data[9] << 8) + ((uint32_t)data[10] << 16) + ((uint32_t)data[11] << 24)); a -= b; a -= c; a ^= (c >> 13); b -= c; b -= a; b ^= (a << 8); c -= a; c -= b; c ^= (b >> 13); data += 12; len -= 12; } c += length; switch (len) { case 11: c += ((uint32_t)data[10] << 24); case 10: c += ((uint32_t)data[9] << 16); case 9: c += ((uint32_t)data[8] << 8); case 8: b += ((uint32_t)data[7] << 24); case 7: b += ((uint32_t)data[6] << 16); case 6: b += ((uint32_t)data[5] << 8); case 5: b += data[4]; case 4: a += ((uint32_t)data[3] << 24); case 3: a += ((uint32_t)data[2] << 16); case 2: a += ((uint32_t)data[1] << 8); case 1: a += data[0]; } a -= b; a -= c; a ^= (c >> 13); b -= c; b -= a; b ^= (a << 8); c -= a; c -= b; c ^= (b >> 13); return c; } ``` 其中,`key` 是输入数据的指针,`length` 是输入数据的长度,`initval` 是初始哈希值。该函数使用三个 32 位的变量 `a`、`b` 和 `c` 来分别保存计算过程中的中间值,使用 `len` 来追踪剩余的数据长度,使用 `data` 来追踪当前处理的输入数据指针。最后,将 `c` 作为哈希值返回。 Jenkins Hash 的优点有: - 易于实现和快速计算。 - 具有良好的散列性能,能够避免哈希冲突,并产生良好的哈希分布。 - 支持增量哈希计算,可以在处理大型数据流时有效地避免内存问题。 由于 Jenkins Hash 的实现简单且性能优秀,因此它被广泛用于各种哈希表、数据结构、散列算法等场合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值