几种常见哈希函数代码实现

几种常见哈希函数的C代码实现

哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。——[百度百科]

在网上各处搜集了一些关于哈希函数具体实现的代码,多出自大家之手,非原创,在实际测试中这些算法没有太大的性能差异。


  1. RS
    Robert SedgwicksAlgorithms in C一书中得到了。原文作者Arash Partow已经添加了一些简单的优化的算法,以加快其散列过程。

    unsigned int RSHash(char* str, unsigned int len)
    {
    unsigned int b    = 378551;
    unsigned int a    = 63689;
    unsigned int hash = 0;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = hash * a + (*str);
      a    = a * b;
    }
    
    return hash;
    }
  2. JS
    Justin Sobel写的一个位操作的哈希函数。

    unsigned int JSHash(char* str, unsigned int len)
    {
    unsigned int hash = 1315423911;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash ^= ((hash << 5) + (*str) + (hash >> 2));
    }
    
    return hash;
  3. PJW
    该散列算法是基于贝尔实验室的彼得J温伯格的的研究。在Compilers一书中(原则,技术和工具),建议采用这个算法的散列函数的哈希方法。

    unsigned int PJWHash(char* str, unsigned int len)
    {
    const unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
    const unsigned int ThreeQuarters     = (unsigned int)((BitsInUnsignedInt  * 3) / 4);
    const unsigned int OneEighth         = (unsigned int)(BitsInUnsignedInt / 8);
    const unsigned int HighBits          = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
    unsigned int hash              = 0;
    unsigned int test              = 0;
    unsigned int i                 = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = (hash << OneEighth) + (*str);
    
      if((test = hash & HighBits)  != 0)
      {
         hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));
      }
    }
    
    return hash;
  4. ELF
    和PJW很相似,在Unix系统中使用的较多。

    unsigned int ELFHash(char* str, unsigned int len)
    {
    unsigned int hash = 0;
    unsigned int x    = 0;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = (hash << 4) + (*str);
      if((x = hash & 0xF0000000L) != 0)
      {
         hash ^= (x >> 24);
      }
      hash &= ~x;
    }
    
    return hash;
    }
  5. BKDR
    这个算法来自Brian KernighanDennis RitchieThe C programming Language。这是一个很简单的哈希算法,使用了一系列奇怪的数字,形式如31,3131,31…31,看上去和DJB算法很相似。

    unsigned int BKDRHash(char* str, unsigned int len)
    {
    unsigned int seed = 131; /* 31 131 1313 13131 131313 etc.. */
    unsigned int hash = 0;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = (hash * seed) + (*str);
    }
    
    return hash;
    }
  6. SDBM
    这个算法在开源的SDBM中使用,似乎对很多不同类型的数据都能得到不错的分布。

    unsigned int SDBMHash(char* str, unsigned int len)
    {
    unsigned int hash = 0;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = (*str) + (hash << 6) + (hash << 16) - hash;
    }
    
    return hash;
    }
  7. DJB
    这个算法是Daniel J.Bernstein 教授发明的,是目前公布的最有效的哈希函数。

    unsigned int DJBHash(char* str, unsigned int len)
    {
    unsigned int hash = 5381;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = ((hash << 5) + hash) + (*str);
    }
    
    return hash;
    }
  8. DEK
    由伟大的Knuth 在《编程的艺术 第三卷》的第六章排序和搜索中给出。

    unsigned int DEKHash(char* str, unsigned int len)
    {
    unsigned int hash = len;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash = ((hash << 5) ^ (hash >> 27)) ^ (*str);
    }
    return hash;
    }
  9. AP
    这是原文作者Arash Partow 贡献的一个哈希函数。

    unsigned int APHash(char* str, unsigned int len)
    {
    unsigned int hash = 0xAAAAAAAA;
    unsigned int i    = 0;
    
    for(i = 0; i < len; str++, i++)
    {
      hash ^= ((i & 1) == 0) ? (  (hash <<  7) ^ (*str) * (hash >> 3)) :
                               (~((hash << 11) + ((*str) ^ (hash >> 5))));
    }
    
    return hash;
    }

你可能感兴趣的:(算法,C)