请求用代码写的Hash码算法

cellblue 2009-04-21 09:17:40
请求用代码写的Hash码算法

我要转换成其它语言的代码,因此寻求Hash的源代码算法
...全文
510 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
yxq4269246 2009-09-16
  • 打赏
  • 举报
回复
初学hash谁能讲讲原理啊!
cellblue 2009-04-22
  • 打赏
  • 举报
回复
看来hash有N种写法了,可能可以引出真Hash和假Hash,但是假Hash也能达到某种效果
计划使用FNVHash1算法来实现我的Hash
yagebu1983 2009-04-21
  • 打赏
  • 举报
回复
这么多啊。。
收藏。。
huangheping520hhp 2009-04-21
  • 打赏
  • 举报
回复
看哈
sushou2009 2009-04-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zsuswy 的回复:]
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 …
[/Quote]
本人比较懒~UP下
ws_hgo 2009-04-21
  • 打赏
  • 举报
回复
关注
热学沸腾56 2009-04-21
  • 打赏
  • 举报
回复
ls太强悍了..头晕...up
cnming 2009-04-21
  • 打赏
  • 举报
回复


/**
* 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
* @remark 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.
* @remark 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 */


cnming 2009-04-21
  • 打赏
  • 举报
回复
.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.
*
* @remark 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
* @remark 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
* @remark 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);


cnming 2009-04-21
  • 打赏
  • 举报
回复


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;
}


cnming 2009-04-21
  • 打赏
  • 举报
回复


/*
* 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
* <27038@mimsy.umd.edu> 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 <rse@engelschall.com>
*/
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;
}

cnming 2009-04-21
  • 打赏
  • 举报
回复
.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;
}


cnming 2009-04-21
  • 打赏
  • 举报
回复
/**//**
* 改进的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;
}
}
cnming 2009-04-21
  • 打赏
  • 举报
回复
这些都有执行到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;
}
zsuswy 2009-04-21
  • 打赏
  • 举报
回复
这里这个你可以看下,还挺不错
http://forums.techpowerup.com/showthread.php?t=62293
Garnett_KG 2009-04-21
  • 打赏
  • 举报
回复
1),自己实现hash函数

2)下个clr的源码去找Object.GetHashCode()的实现
http://www.microsoft.com/downloads/details.aspx?FamilyID=8c09fd61-3f26-4555-ae17-3121b4f51d4d&displaylang=en
zsuswy 2009-04-21
  • 打赏
  • 举报
回复
另外也可以去反编译.net的类库的源代码,里面可以看到相关的hash算法,推荐用工具reflector反编译工具.
zsuswy 2009-04-21
  • 打赏
  • 举报
回复
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);
}
}
tabbycat 2009-04-21
  • 打赏
  • 举报
回复
看看.net这部分是不是开源了
zcandyly20211 2009-04-21
  • 打赏
  • 举报
回复
友情up!

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧