请求用代码写的Hash码算法我要转换成其它语言的代码,因此寻求Hash的源代码算法

解决方案 »

  1.   

    public class SimpleHash
    {
        public static string ComputeHash(string   plainText,
                                         string   hashAlgorithm,
                                         byte[]   saltBytes)
        {
            // If salt is not specified, generate it on the fly.
            if (saltBytes == null)
            {
                // Define min and max salt sizes.
                int minSaltSize = 4;
                int maxSaltSize = 8;            // Generate a random number for the size of the salt.
                Random  random = new Random();
                int saltSize = random.Next(minSaltSize, maxSaltSize);            // Allocate a byte array, which will hold the salt.
                saltBytes = new byte[saltSize];            // Initialize a random number generator.
                RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();            // Fill the salt with cryptographically strong byte values.
                rng.GetNonZeroBytes(saltBytes); 
            }
            
            // Convert plain text into a byte array.
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            
            // Allocate array, which will hold plain text and salt.
            byte[] plainTextWithSaltBytes = 
                    new byte[plainTextBytes.Length + saltBytes.Length];        // Copy plain text bytes into resulting array.
            for (int i=0; i < plainTextBytes.Length; i++)
                plainTextWithSaltBytes[i] = plainTextBytes[i];
            
            // Append salt bytes to the resulting array.
            for (int i=0; i < saltBytes.Length; i++)
                plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];        // Because we support multiple hashing algorithms, we must define
            // hash object as a common (abstract) base class. We will specify the
            // actual hashing algorithm class later during object creation.
            HashAlgorithm hash;
            
            // Make sure hashing algorithm name is specified.
            if (hashAlgorithm == null)
                hashAlgorithm = "";
            
            // Initialize appropriate hashing algorithm class.
            switch (hashAlgorithm.ToUpper())
            {
                case "SHA1":
                    hash = new SHA1Managed();
                    break;            case "SHA256":
                    hash = new SHA256Managed();
                    break;            case "SHA384":
                    hash = new SHA384Managed();
                    break;            case "SHA512":
                    hash = new SHA512Managed();
                    break;            default:
                    hash = new MD5CryptoServiceProvider();
                    break;
            }
            
            // Compute hash value of our plain text with appended salt.
            byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
            
            // Create array which will hold hash and original salt bytes.
            byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
                                                saltBytes.Length];
            
            // Copy hash bytes into resulting array.
            for (int i=0; i < hashBytes.Length; i++)
                hashWithSaltBytes[i] = hashBytes[i];
                
            // Append salt bytes to the result.
            for (int i=0; i < saltBytes.Length; i++)
                hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];
                
            // Convert result into a base64-encoded string.
            string hashValue = Convert.ToBase64String(hashWithSaltBytes);
            
            // Return the result.
            return hashValue;
        }
        public static bool VerifyHash(string   plainText,
                                      string   hashAlgorithm,
                                      string   hashValue)
        {
            // Convert base64-encoded hash value into a byte array.
            byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue);
            
            // We must know size of hash (without salt).
            int hashSizeInBits, hashSizeInBytes;
            
            // Make sure that hashing algorithm name is specified.
            if (hashAlgorithm == null)
                hashAlgorithm = "";
            
            // Size of hash is based on the specified algorithm.
            switch (hashAlgorithm.ToUpper())
            {
                case "SHA1":
                    hashSizeInBits = 160;
                    break;            case "SHA256":
                    hashSizeInBits = 256;
                    break;            case "SHA384":
                    hashSizeInBits = 384;
                    break;            case "SHA512":
                    hashSizeInBits = 512;
                    break;            default: // Must be MD5
                    hashSizeInBits = 128;
                    break;
            }        // Convert size of hash from bits to bytes.
            hashSizeInBytes = hashSizeInBits / 8;        // Make sure that the specified hash value is long enough.
            if (hashWithSaltBytes.Length < hashSizeInBytes)
                return false;        // Allocate array to hold original salt bytes retrieved from hash.
            byte[] saltBytes = new byte[hashWithSaltBytes.Length - 
                                        hashSizeInBytes];        // Copy salt from the end of the hash to the new array.
            for (int i=0; i < saltBytes.Length; i++)
                saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];        // Compute a new hash string.
            string expectedHashString = 
                        ComputeHash(plainText, hashAlgorithm, saltBytes);        // If the computed hash matches the specified hash,
            // the plain text value must be correct.
            return (hashValue == expectedHashString);
        }
    }
      

  2.   

    另外也可以去反编译.net的类库的源代码,里面可以看到相关的hash算法,推荐用工具reflector反编译工具.
      

  3.   

    1),自己实现hash函数2)下个clr的源码去找Object.GetHashCode()的实现
    http://www.microsoft.com/downloads/details.aspx?FamilyID=8c09fd61-3f26-4555-ae17-3121b4f51d4d&displaylang=en
      

  4.   

    这里这个你可以看下,还挺不错
    http://forums.techpowerup.com/showthread.php?t=62293
      

  5.   

    这些都有执行到Hash的效果,就是不清楚是否满足你的使用不过是C++的代码/**
    * Hash算法大全<br>
    * 推荐使用FNV1算法
    * @algorithm None
    * @author Goodzzp 2006-11-20
    * @lastEdit Goodzzp 2006-11-20
    * @editDetail Create
    */
    public class HashAlgorithms
    {
         /**//**
         * 加法hash
         * @param key 字符串
         * @param prime 一个质数
         * @return hash结果
         */
         public static int additiveHash(String key, int prime)
         {
             int hash, i;
             for (hash = key.length(), i = 0; i < key.length(); i++)
                 hash += key.charAt(i);
             return (hash % prime);
         }
        
         /**//**
         * 旋转hash
         * @param key 输入字符串
         * @param prime 质数
         * @return hash值
         */
         public static int rotatingHash(String key, int prime)
         {
             int hash, i;
             for (hash=key.length(), i=0; i<key.length(); ++i)
                 hash = (hash<<4)^(hash>>28)^key.charAt(i);
             return (hash % prime);
             //   return (hash ^ (hash>>10) ^ (hash>>20));
         }
        
         // 替代:
         // 使用:hash = (hash ^ (hash>>10) ^ (hash>>20)) & mask;
         // 替代:hash %= prime;     /**//**
         * MASK值,随便找一个值,最好是质数
         */
         static int M_MASK = 0x8765fed1;
         /**//**
         * 一次一个hash
         * @param key 输入字符串
         * @return 输出hash值
         */
         public static int oneByOneHash(String key)
         {
             int   hash, i;
             for (hash=0, i=0; i<key.length(); ++i)
             {
                 hash += key.charAt(i);
                 hash += (hash << 10);
                 hash ^= (hash >> 6);
             }
             hash += (hash << 3);
             hash ^= (hash >> 11);
             hash += (hash << 15);
             //   return (hash & M_MASK);
             return hash;
         }
        
         /**//**
         * Bernstein's hash
         * @param key 输入字节数组
         * @param level 初始hash常量
         * @return 结果hash
         */
         public static int bernstein(String key)
         {
             int hash = 0;
             int i;
             for (i=0; i<key.length(); ++i) hash = 33*hash + key.charAt(i);
             return hash;
         }
        
         //
         /**///// Pearson's Hash
         // char pearson(char[]key, ub4 len, char tab[256])
         // {
         //   char hash;
         //   ub4 i;
         //   for (hash=len, i=0; i<len; ++i)
         //     hash=tab[hash^key[i]];
         //   return (hash);
         // }
        
         /**///// CRC Hashing,计算crc,具体代码见其他
         // ub4 crc(char *key, ub4 len, ub4 mask, ub4 tab[256])
         // {
         //   ub4 hash, i;
         //   for (hash=len, i=0; i<len; ++i)
         //     hash = (hash >> 8) ^ tab[(hash & 0xff) ^ key[i]];
         //   return (hash & mask);
         // }
        
         /**//**
         * Universal Hashing
         */
         public static int universal(char[]key, int mask, int[] tab)
         {
             int hash = key.length, i, len = key.length;
             for (i=0; i<(len<<3); i+=8)
             {
                 char k = key[i>>3];
                 if ((k&0x01) == 0) hash ^= tab[i+0];
                 if ((k&0x02) == 0) hash ^= tab[i+1];
                 if ((k&0x04) == 0) hash ^= tab[i+2];
                 if ((k&0x08) == 0) hash ^= tab[i+3];
                 if ((k&0x10) == 0) hash ^= tab[i+4];
                 if ((k&0x20) == 0) hash ^= tab[i+5];
                 if ((k&0x40) == 0) hash ^= tab[i+6];
                 if ((k&0x80) == 0) hash ^= tab[i+7];
             }
             return (hash & mask);
         }
        
         /**//**
         * Zobrist Hashing
         */
         public static int zobrist( char[] key,int mask, int[][] tab)
         {
             int hash, i;
             for (hash=key.length, i=0; i<key.length; ++i)
                 hash ^= tab[i][key[i]];
             return (hash & mask);
         }
        
         // LOOKUP3
         // 见Bob Jenkins(3).c文件
        
         // 32位FNV算法
         static int M_SHIFT = 0;
         /**//**
         * 32位的FNV算法
         * @param data 数组
         * @return int值
         */
         public static int FNVHash(byte[] data)
         {
             int hash = (int)2166136261L;
             for(byte b : data)
                 hash = (hash * 16777619) ^ b;
             if (M_SHIFT == 0)
                 return hash;
             return (hash ^ (hash >> M_SHIFT)) & M_MASK;
         }
         /**//**
         * 改进的32位FNV算法1
         * @param data 数组
         * @return int值
         */
         public static int FNVHash1(byte[] data)
         {
             final int p = 16777619;
             int hash = (int)2166136261L;
             for(byte b:data)
                 hash = (hash ^ b) * p;
             hash += hash << 13;
             hash ^= hash >> 7;
             hash += hash << 3;
             hash ^= hash >> 17;
             hash += hash << 5;
             return hash;
         }
      

  6.   

         /**//**
         * 改进的32位FNV算法1
         * @param data 字符串
         * @return int值
         */
         public static int FNVHash1(String data)
         {
             final int p = 16777619;
             int hash = (int)2166136261L;
             for(int i=0;i<data.length();i++)
                 hash = (hash ^ data.charAt(i)) * p;
             hash += hash << 13;
             hash ^= hash >> 7;
             hash += hash << 3;
             hash ^= hash >> 17;
             hash += hash << 5;
             return hash;
         }
        
         /**//**
         * Thomas Wang的算法,整数hash
         */
         public static int intHash(int key)
         {
             key += ~(key << 15);
             key ^= (key >>> 10);
             key += (key << 3);
             key ^= (key >>> 6);
             key += ~(key << 11);
             key ^= (key >>> 16);
             return key;
         }
         /**//**
         * RS算法hash
         * @param str 字符串
         */
         public static int RSHash(String str)
         {
             int b     = 378551;
             int a     = 63689;
             int hash = 0;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash = hash * a + str.charAt(i);
                 a     = a * b;
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of RS Hash Function */
        
         /**//**
         * JS算法
         */
         public static int JSHash(String str)
         {
             int hash = 1315423911;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2));
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of JS Hash Function */
        
         /**//**
         * PJW算法
         */
         public static int PJWHash(String str)
         {
             int BitsInUnsignedInt = 32;
             int ThreeQuarters     = (BitsInUnsignedInt * 3) / 4;
             int OneEighth         = BitsInUnsignedInt / 8;
             int HighBits           = 0xFFFFFFFF << (BitsInUnsignedInt - OneEighth);
             int hash               = 0;
             int test               = 0;
            
             for(int i = 0; i < str.length();i++)
             {
                 hash = (hash << OneEighth) + str.charAt(i);
                
                 if((test = hash & HighBits) != 0)
                 {
                     hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));
                 }
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of P. J. Weinberger Hash Function */
        
         /**//**
         * ELF算法
         */
         public static int ELFHash(String str)
         {
             int hash = 0;
             int x     = 0;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash = (hash << 4) + str.charAt(i);
                 if((x = (int)(hash & 0xF0000000L)) != 0)
                 {
                     hash ^= (x >> 24);
                     hash &= ~x;
                 }
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of ELF Hash Function */
        
         /**//**
         * BKDR算法
         */
         public static int BKDRHash(String str)
         {
             int seed = 131; // 31 131 1313 13131 131313 etc..
             int hash = 0;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash = (hash * seed) + str.charAt(i);
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of BKDR Hash Function */
        
         /**//**
         * SDBM算法
         */
         public static int SDBMHash(String str)
         {
             int hash = 0;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash;
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of SDBM Hash Function */
        
         /**//**
         * DJB算法
         */
         public static int DJBHash(String str)
         {
             int hash = 5381;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash = ((hash << 5) + hash) + str.charAt(i);
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of DJB Hash Function */
        
         /**//**
         * DEK算法
         */
         public static int DEKHash(String str)
         {
             int hash = str.length();
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);
             }
            
             return (hash & 0x7FFFFFFF);
         }
         /**//* End Of DEK Hash Function */
        
         /**//**
         * AP算法
         */
         public static int APHash(String str)
         {
             int hash = 0;
            
             for(int i = 0; i < str.length(); i++)
             {
                 hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ str.charAt(i) ^ (hash >> 3)) :
             (~((hash << 11) ^ str.charAt(i) ^ (hash >> 5)));
             }
            
             //       return (hash & 0x7FFFFFFF);
             return hash;
         }
         /**//* End Of AP Hash Function */
        
         /**//**
         * JAVA自己带的算法
         */
         public static int java(String str)
         {
             int h = 0;
             int off = 0;
             int len = str.length();
             for (int i = 0; i < len; i++)
             {
                 h = 31 * h + str.charAt(off++);
             }
             return h;
         }
        
         /**//**
         * 混合hash算法,输出64位的值
         */
         public static long mixHash(String str)
         {
             long hash = str.hashCode();
             hash <<= 32;
             hash |= FNVHash1(str);
             return hash;
         }
    }
      

  7.   

    .CPP的代码
    /* Copyright 2000-2004 The Apache Software Foundation
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. * split from apache for general usage by Yankee
     * use system malloc instead of apr_pool ,although it is not so effiecient but suitable for small
     * scale usage.
    *///#include "apr_private.h"//#include "apr_general.h"
    //#include "apr_pools.h"#include "hash_modify.h"//#if APR_HAVE_STDLIB_H
    #include <stdlib.h>
    //#endif
    //#if APR_HAVE_STRING_H
    #include <string.h>
    //#endif
    /*
     * The internal form of a hash table.
     *
     * The table is an array indexed by the hash of the key; collisions
     * are resolved by hanging a linked list of hash entries off each
     * element of the array. Although this is a really simple design it
     * isn't too bad given that pools have a low allocation overhead.
     */typedef struct apr_hash_entry_t apr_hash_entry_t;struct apr_hash_entry_t {
        apr_hash_entry_t *next;
        unsigned int      hash;
        const void       *key;
        apr_ssize_t       klen;
        const void       *val;
    };/*
     * Data structure for iterating through a hash table.
     *
     * We keep a pointer to the next hash entry here to allow the current
     * hash entry to be freed or otherwise mangled between calls to
     * apr_hash_next().
     */
    struct apr_hash_index_t {
        apr_hash_t         *ht;
        apr_hash_entry_t   *this, *next;
        unsigned int        index;
    };/*
     * The size of the array is always a power of two. We use the maximum
     * index rather than the size so that we can use bitwise-AND for
     * modular arithmetic.
     * The count of hash entries may be greater depending on the chosen
     * collision rate.
     */
    struct apr_hash_t {
        apr_pool_t          *pool;
        apr_hash_entry_t   **array;
        apr_hash_index_t     iterator;  /* For apr_hash_first(NULL, ...) */
        unsigned int         count, max;
    };#define INITIAL_MAX 15 /* tunable == 2^n - 1 */
    /*
     * Hash creation functions.
     */static apr_hash_entry_t **alloc_array(apr_hash_t *ht, unsigned int max)
    {
       return malloc(ht->pool, sizeof(*ht->array) * (max + 1));
    }apr_hash_t * apr_hash_make(void)
    {
        apr_hash_t *ht;
        ht =malloc(pool, sizeof(apr_hash_t));
        ht->pool = pool;
        ht->count = 0;
        ht->max = INITIAL_MAX;
        ht->array = alloc_array(ht, ht->max);
        return ht;
    }
    /*
     * Hash iteration functions.
     */apr_hash_index_t * apr_hash_next(apr_hash_index_t *hi)
    {
        hi->this = hi->next;
        while (!hi->this) {
            if (hi->index > hi->ht->max)
                return NULL;        hi->this = hi->ht->array[hi->index++];
        }
        hi->next = hi->this->next;
        return hi;
    }apr_hash_index_t * apr_hash_first(apr_pool_t *p, apr_hash_t *ht)
    {
        apr_hash_index_t *hi;
        if (p)
            hi = malloc(p, sizeof(*hi));
        else
            hi = &ht->iterator;    hi->ht = ht;
        hi->index = 0;
        hi->this = NULL;
        hi->next = NULL;
        return apr_hash_next(hi);
    }void apr_hash_this(apr_hash_index_t *hi,
                                    const void **key,
                                    apr_ssize_t *klen,
                                    void **val)
    {
        if (key)  *key  = hi->this->key;
        if (klen) *klen = hi->this->klen;
        if (val)  *val  = (void *)hi->this->val;
    }
    /*
     * Expanding a hash table
     */static void expand_array(apr_hash_t *ht)
    {
        apr_hash_index_t *hi;
        apr_hash_entry_t **new_array;
        unsigned int new_max;    new_max = ht->max * 2 + 1;
        new_array = alloc_array(ht, new_max);
        for (hi = apr_hash_first(NULL, ht); hi; hi = apr_hash_next(hi)) {
            unsigned int i = hi->this->hash & new_max;
            hi->this->next = new_array[i];
            new_array[i] = hi->this;
        }
        ht->array = new_array;
        ht->max = new_max;
    }
      

  8.   

    /*
     * This is where we keep the details of the hash function and control
     * the maximum collision rate.
     *
     * If val is non-NULL it creates and initializes a new hash entry if
     * there isn't already one there; it returns an updatable pointer so
     * that hash entries can be removed.
     */static apr_hash_entry_t **find_entry(apr_hash_t *ht,
                                         const void *key,
                                         apr_ssize_t klen,
                                         const void *val)
    {
        apr_hash_entry_t **hep, *he;
        const unsigned char *p;
        unsigned int hash;
        apr_ssize_t i;    /*
         * This is the popular `times 33' hash algorithm which is used by
         * perl and also appears in Berkeley DB. This is one of the best
         * known hash functions for strings because it is both computed
         * very fast and distributes very well.
         *
         * The originator may be Dan Bernstein but the code in Berkeley DB
         * cites Chris Torek as the source. The best citation I have found
         * is "Chris Torek, Hash function for text in C, Usenet message
         * <[email protected]> in comp.lang.c , October, 1990." in Rich
         * Salz's USENIX 1992 paper about INN which can be found at
         * <http://citeseer.nj.nec.com/salz92internetnews.html>.
         *
         * The magic of number 33, i.e. why it works better than many other
         * constants, prime or not, has never been adequately explained by
         * anyone. So I try an explanation: if one experimentally tests all
         * multipliers between 1 and 256 (as I did while writing a low-level
         * data structure library some time ago) one detects that even
         * numbers are not useable at all. The remaining 128 odd numbers
         * (except for the number 1) work more or less all equally well.
         * They all distribute in an acceptable way and this way fill a hash
         * table with an average percent of approx. 86%.
         *
         * If one compares the chi^2 values of the variants (see
         * Bob Jenkins ``Hashing Frequently Asked Questions'' at
         * http://burtleburtle.net/bob/hash/hashfaq.html for a description
         * of chi^2), the number 33 not even has the best value. But the
         * number 33 and a few other equally good numbers like 17, 31, 63,
         * 127 and 129 have nevertheless a great advantage to the remaining
         * numbers in the large set of possible multipliers: their multiply
         * operation can be replaced by a faster operation based on just one
         * shift plus either a single addition or subtraction operation. And
         * because a hash function has to both distribute good _and_ has to
         * be very fast to compute, those few numbers should be preferred.
         *
         *                  -- Ralf S. Engelschall <[email protected]>
         */
        hash = 0;
        if (klen == APR_HASH_KEY_STRING) {
            for (p = key; *p; p++) {
                hash = hash * 33 + *p;
            }
            klen = p - (const unsigned char *)key;
        }
        else {
            for (p = key, i = klen; i; i--, p++) {
                hash = hash * 33 + *p;
            }
        }    /* scan linked list */
        //????
        for (hep = &ht->array[hash & ht->max], he = *hep;
             he; hep = &he->next, he = *hep) {
            if (he->hash == hash
                && he->klen == klen
                && memcmp(he->key, key, klen) == 0)
                break;
        }
        if (he || !val)
            return hep;    /* add a new entry for non-NULL values */
        he = malloc(ht->pool, sizeof(*he));
        he->next = NULL;
        he->hash = hash;
        he->key  = key;
        he->klen = klen;
        he->val  = val;
        *hep = he;
        ht->count++;
        return hep;
    }apr_hash_t * apr_hash_copy(apr_pool_t *pool,
                                            const apr_hash_t *orig)
    {
        apr_hash_t *ht;
        apr_hash_entry_t *new_vals;
        unsigned int i, j;    ht = apr_palloc(pool, sizeof(apr_hash_t) +
                        sizeof(*ht->array) * (orig->max + 1) +
                        sizeof(apr_hash_entry_t) * orig->count);
        ht->pool = pool;
        ht->count = orig->count;
        ht->max = orig->max;
        ht->array = (apr_hash_entry_t **)((char *)ht + sizeof(apr_hash_t));    new_vals = (apr_hash_entry_t *)((char *)(ht) + sizeof(apr_hash_t) +
                                        sizeof(*ht->array) * (orig->max + 1));
        j = 0;
        for (i = 0; i <= ht->max; i++) {
            apr_hash_entry_t **new_entry = &(ht->array[i]);
            apr_hash_entry_t *orig_entry = orig->array[i];
            while (orig_entry) {
                *new_entry = &new_vals[j++];
                (*new_entry)->hash = orig_entry->hash;
                (*new_entry)->key = orig_entry->key;
                (*new_entry)->klen = orig_entry->klen;
                (*new_entry)->val = orig_entry->val;
                new_entry = &((*new_entry)->next);
                orig_entry = orig_entry->next;
            }
            *new_entry = NULL;
        }
        return ht;
    }
      

  9.   

    void * apr_hash_get(apr_hash_t *ht,
                                     const void *key,
                                     apr_ssize_t klen)
    {
        apr_hash_entry_t *he;
        he = *find_entry(ht, key, klen, NULL);
        if (he)
            return (void *)he->val;
        else
            return NULL;
    }void apr_hash_set(apr_hash_t *ht,
                                   const void *key,
                                   apr_ssize_t klen,
                                   const void *val)
    {
        apr_hash_entry_t **hep;
        hep = find_entry(ht, key, klen, val);
        if (*hep) {
            if (!val) {
                /* delete entry */
                *hep = (*hep)->next;
                --ht->count;
            }
            else {
                /* replace entry */
                (*hep)->val = val;
                /* check that the collision rate isn't too high */
                if (ht->count > ht->max) {
                    expand_array(ht);
                }
            }
        }
        /* else key not present and val==NULL */
    }unsigned intapr_hash_count(apr_hash_t *ht)
    {
        return ht->count;
    }apr_hash_t* apr_hash_overlay(apr_pool_t *p,
                                              const apr_hash_t *overlay,
                                              const apr_hash_t *base)
    {
        return apr_hash_merge(p, overlay, base, NULL, NULL);
    }apr_hash_t *apr_hash_merge(apr_pool_t *p,
                                             const apr_hash_t *overlay,
                                             const apr_hash_t *base,
                                             void * (*merger)(apr_pool_t *p,
                                                         const void *key,
                                                         apr_ssize_t klen,
                                                         const void *h1_val,
                                                         const void *h2_val,
                                                         const void *data),
                                             const void *data)
    {
        apr_hash_t *res;
        apr_hash_entry_t *new_vals = NULL;
        apr_hash_entry_t *iter;
        apr_hash_entry_t *ent;
        unsigned int i,j,k;
        res = malloc(p, sizeof(apr_hash_t));
        res->pool = p;
        res->count = base->count;
        res->max = (overlay->max > base->max) ? overlay->max : base->max;
        if (base->count + overlay->count > res->max) {
            res->max = res->max * 2 + 1;
        }
        res->array = alloc_array(res, res->max);
        if (base->count + overlay->count) {
            new_vals =  malloc(p, sizeof(apr_hash_entry_t) *
                                  (base->count + overlay->count));
        }
        j = 0;
        for (k = 0; k <= base->max; k++) {
            for (iter = base->array[k]; iter; iter = iter->next) {
                i = iter->hash & res->max;
                new_vals[j].klen = iter->klen;
                new_vals[j].key = iter->key;
                new_vals[j].val = iter->val;
                new_vals[j].hash = iter->hash;
                new_vals[j].next = res->array[i];
                res->array[i] = &new_vals[j];
                j++;
            }
        }    for (k = 0; k <= overlay->max; k++) {
            for (iter = overlay->array[k]; iter; iter = iter->next) {
                i = iter->hash & res->max;
                for (ent = res->array[i]; ent; ent = ent->next) {
                    if ((ent->klen == iter->klen) &&
                        (memcmp(ent->key, iter->key, iter->klen) == 0)) {
                        if (merger) {
                            ent->val = (*merger)(p, iter->key, iter->klen,
                                                 iter->val, ent->val, data);
                        }
                        else {
                            ent->val = iter->val;
                        }
                        break;
                    }
                }
                if (!ent) {
                    new_vals[j].klen = iter->klen;
                    new_vals[j].key = iter->key;
                    new_vals[j].val = iter->val;
                    new_vals[j].hash = iter->hash;
                    new_vals[j].next = res->array[i];
                    res->array[i] = &new_vals[j];
                    res->count++;
                    j++;
                }
            }
        }
        return res;
    }
      

  10.   

    .h的文件/* Copyright 2000-2004 The Apache Software Foundation
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */#ifndef APR_HASH_H
    #define APR_HASH_H/**
     * @file apr_hash.h
     * @brief APR Hash Tables
     */#ifdef __cplusplus
    extern "C" {
    #endif/**
     * @defgroup apr_hash Hash Tables
     * @ingroup APR 
     * @{
     *//**
     * When passing a key to apr_hash_set or apr_hash_get, this value can be
     * passed to indicate a string-valued key, and have apr_hash compute the
     * length automatically.
     *
     * @re apr_hash will use strlen(key) for the length. The null-terminator
     *         is not included in the hash value (why throw a constant in?).
     *         Since the hash table merely references the provided key (rather
     *         than copying it), apr_hash_this() will return the null-term'd key.
     */
    #define APR_HASH_KEY_STRING     (-1)/**
     * Abstract type for hash tables.
     */
    typedef struct apr_hash_t apr_hash_t;/**
     * Abstract type for scanning hash tables.
     */
    typedef struct apr_hash_index_t apr_hash_index_t;/**
     * Create a hash table.
     * @param pool The pool to allocate the hash table out of
     * @return The hash table just created
      */
    pr_hash_t * apr_hash_make(apr_pool_t *pool);/**
     * Make a copy of a hash table
     * @param pool The pool from which to allocate the new hash table
     * @param h The hash table to clone
     * @return The hash table just created
     * @re Makes a shallow copy
     */
    apr_hash_t * apr_hash_copy(apr_pool_t *pool,
                                            const apr_hash_t *h);/**
     * Associate a value with a key in a hash table.
     * @param ht The hash table
     * @param key Pointer to the key
     * @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
     * @param val Value to associate with the key
     * @re If the value is NULL the hash entry is deleted.
     */
    void apr_hash_set(apr_hash_t *ht, const void *key,
                                   apr_ssize_t klen, const void *val);/**
     * Look up the value associated with a key in a hash table.
     * @param ht The hash table
     * @param key Pointer to the key
     * @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
     * @return Returns NULL if the key is not present.
     */
    void * apr_hash_get(apr_hash_t *ht, const void *key,
                                     apr_ssize_t klen);
      

  11.   

    /**
     * Start iterating over the entries in a hash table.
     * @param p The pool to allocate the apr_hash_index_t iterator. If this
     *          pool is NULL, then an internal, non-thread-safe iterator is used.
     * @param ht The hash table
     * @re  There is no restriction on adding or deleting hash entries during
     * an iteration (although the results may be unpredictable unless all you do
     * is delete the current entry) and multiple iterations can be in
     * progress at the same time. * @example
     */
    /**
     * <PRE>
     * 
     * int sum_values(apr_pool_t *p, apr_hash_t *ht)
     * {
     *     apr_hash_index_t *hi;
     *     void *val;
     *     int sum = 0;
     *     for (hi = apr_hash_first(p, ht); hi; hi = apr_hash_next(hi)) {
     *         apr_hash_this(hi, NULL, NULL, &val);
     *         sum += *(int *)val;
     *     }
     *     return sum;
     * }
     * </PRE>
     */
    apr_hash_index_t * apr_hash_first(apr_pool_t *p, apr_hash_t *ht);/**
     * Continue iterating over the entries in a hash table.
     * @param hi The iteration state
     * @return a pointer to the updated iteration state.  NULL if there are no more  
     *         entries.
     */
    apr_hash_index_t * apr_hash_next(apr_hash_index_t *hi);/**
     * Get the current entry's details from the iteration state.
     * @param hi The iteration state
     * @param key Return pointer for the pointer to the key.
     * @param klen Return pointer for the key length.
     * @param val Return pointer for the associated value.
     * @re The return pointers should point to a variable that will be set to the
     *         corresponding data, or they may be NULL if the data isn't interesting.
     */
    void apr_hash_this(apr_hash_index_t *hi, const void **key, 
                                    apr_ssize_t *klen, void **val);/**
     * Get the number of key/value pairs in the hash table.
     * @param ht The hash table
     * @return The number of key/value pairs in the hash table.
     */
    unsigned int apr_hash_count(apr_hash_t *ht);/**
     * Merge two hash tables into one new hash table. The values of the overlay
     * hash override the values of the base if both have the same key.
     * @param p The pool to use for the new hash table
     * @param overlay The table to add to the initial table
     * @param base The table that represents the initial values of the new table
     * @return A new hash table containing all of the data from the two passed in
     */
    apr_hash_t * apr_hash_overlay(apr_pool_t *p,
                                               const apr_hash_t *overlay, 
                                               const apr_hash_t *base);/**
     * Merge two hash tables into one new hash table. If the same key
     * is present in both tables, call the supplied merge function to
     * produce a merged value for the key in the new table.
     * @param p The pool to use for the new hash table
     * @param h1 The first of the tables to merge
     * @param h2 The second of the tables to merge
     * @param merger A callback function to merge values, or NULL to
     *  make values from h1 override values from h2 (same semantics as
     *  apr_hash_overlay())
     * @param data Client data to pass to the merger function
     * @return A new hash table containing all of the data from the two passed in
     */
    apr_hash_t *apr_hash_merge(apr_pool_t *p,
                                             const apr_hash_t *h1,
                                             const apr_hash_t *h2,
                                             void * (*merger)(apr_pool_t *p,
                                                         const void *key,
                                                         apr_ssize_t klen,
                                                         const void *h1_val,
                                                         const void *h2_val,
                                                         const void *data),
                                             const void *data);/** @} */#ifdef __cplusplus
    }
    #endif#endif /* !APR_HASH_H */
      

  12.   

    看来hash有N种写法了,可能可以引出真Hash和假Hash,但是假Hash也能达到某种效果
    计划使用FNVHash1算法来实现我的Hash