⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 linux或unix下回话劫持工具
💻 C
字号:
/* *  *	This is free software. You can redistribute it and/or modify under *	the terms of the GNU General Public License version 2. * * 	Copyright (C) 1998 by kra *  */#include <stdlib.h>#include <string.h>#include <assert.h>#include <stdio.h>#include "hash.h"static int __chose_table_size(int size){	static int ht_size[] = {		37, 47, 79, 97, 163, 197, 331, 397, 673, 797, 1361, 1597,		2729, 3203, 5471, 6421, 10949, 12853, 21911, 25717, 43853,		51437, 87719, 102877, 175447, 205759, 350899, 411527, 701819,		823117, 1403641, 1646237, 2807303, 3292489, 5614657, 6584983,		11229331, 13169977, 22458671, 26339969, 44917381, 52679969,		89834777, 105359939	};	int i;		if (size >= ht_size[sizeof(ht_size) / sizeof(ht_size[0]) - 1])	    return ht_size[sizeof(ht_size) / sizeof(ht_size[0])];	for (i = 0; ht_size[i] < size; i++)	    ;	return ht_size[i];}static inline int __when_need_space(int max_items){	return (HASH_MAX_PCT_FULL * max_items) / 100;}static inline int __hash_need_space(struct hash *h){	return h->h_items >= h->h_space_after ? 1 : 0;//	return (h->h_items * 100) / h->h_max_items >= HASH_MAX_PCT_FULL ? 1 : 0;}int hash_init(struct hash *h, int max_items, hash_equal_func eqfunc){	if (max_items < HASH_MIN_ITEMS)		max_items = HASH_MIN_ITEMS;	max_items = __chose_table_size(max_items);	h->h_space_after = __when_need_space(max_items);	h->h_items = 0;	h->h_max_items = max_items;	h->h_eqfunc = eqfunc;	if (!(h->h_table = malloc(max_items * sizeof(struct hash_table_item))))		return -1;	memset(h->h_table, 0, max_items * sizeof(struct hash_table_item));#ifdef _REENTRANT	h->h_locked = 0;	pthread_mutex_init(&h->h_mutex, NULL);#endif	return 0;}void hash_free(struct hash *h){	if (h->h_table)		free(h->h_table);	memset(h, 0, sizeof(*h));}static unsigned int __hv_hash;static unsigned int __hv_hash_save;static unsigned int __hv_max_items;#ifdef HASH_FUNC_2static unsigned int __hv_d;static unsigned int __hv_d_save;#endifstatic inline int __hv(unsigned int key, unsigned int max_items){	__hv_max_items = max_items;#ifdef HASH_FUNC_2	__hv_d = 2;#endif	return (int)(__hv_hash = key % max_items);}static inline int __hv_peek(void){	return __hv_hash;}static inline int __hv_next(void){#ifdef HASH_FUNC_2	__hv_hash = (__hv_hash + __hv_d) % __hv_max_items;	__hv_d += 2;	return (int)__hv_hash;#else	return __hv_hash = (__hv_hash + 1) % __hv_max_items;#endif}static inline int __hv_peek_next(void){#ifdef HASH_FUNC2	return (int)((__hv_hash + __hv_d) % __hv_max_items);#else	return (__hv_hash + 1) % __hv_max_items;#endif}static inline void __hv_save_position(void){#ifdef HASH_FUNC_2	__hv_d_save = __hv_d;#endif	__hv_hash_save = __hv_hash;}static inline int __hv_load_position(void){#ifdef HASH_FUNC_2	__hv_d = __hv_d_save;#endif	return (int)(__hv_hash = __hv_hash_save);}static int __hash_find(struct hash *h, unsigned int key, void *arg){		int retval;	int hv;	struct hash_table_item *h_table;		hv = __hv(key, h->h_max_items);	h_table = h->h_table;	retval = -1;		while (h_table[hv].ht_data) {		if (h_table[hv].ht_key == key) {			if (!h->h_eqfunc || 			    h_table[__hv_peek_next()].ht_data == NULL) {				retval = hv;				break;			} else {				if (h->h_eqfunc(key, h_table[hv].ht_data, arg)) {					retval = hv;					break;				}			}		}		hv = __hv_next();	}	return retval;}static void __hash_put(struct hash *h, unsigned int key, void *data){	int hv;	struct hash_table_item *h_table;		hv = __hv(key, h->h_max_items);	h_table = h->h_table;	while (h_table[hv].ht_data) {		hv = __hv_next();	}	h_table[hv].ht_key = key;	h_table[hv].ht_data = data;	h->h_items++;}static int __hash_put_check(struct hash *h, unsigned int key,			     void *data, void *arg){	int retval;	int hv;	struct hash_table_item *h_table = h->h_table;		retval = __hash_find(h, key, arg);	if (retval < 0) {		hv = __hv_peek();		h_table[hv].ht_key = key;		h_table[hv].ht_data = data;		return 0;	} else		return -1;}static void __hash_remap(struct hash *h, int hv){	int count, i;	struct hash_table_item *h_table, *ht_save;		__hv_save_position();	h_table = h->h_table;	count = 0;	while (h_table[hv].ht_data) {		count++;		hv = __hv_next();	}	if (count) {		ht_save = alloca(count * sizeof(struct hash_table_item));		hv = __hv_load_position();		i = 0;		while (h_table[hv].ht_data) {			ht_save[i].ht_key = h_table[hv].ht_key;			ht_save[i].ht_data = h_table[hv].ht_data;			h_table[hv].ht_key = 0;			h_table[hv].ht_data = NULL;			i++;			hv = __hv_next();		}		h->h_items -= count;		for (i = 0; i < count; i++)			__hash_put(h, ht_save[i].ht_key, ht_save[i].ht_data);	}}static void __hash_new_space(struct hash *h){	struct hash_table_item *old_h_table;	int old_items, old_max_items;	int i;	old_items = h->h_items;	old_max_items = h->h_max_items;	old_h_table = h->h_table;		h->h_max_items = __chose_table_size(h->h_max_items + 		(HASH_SPACE_PCT_INC * h->h_max_items) / 100);	if (!(h->h_table = malloc(h->h_max_items * sizeof(struct hash_table_item)))) {		h->h_items = old_items;		h->h_max_items = old_max_items;		h->h_table = old_h_table;		return;	}	h->h_space_after = __when_need_space(h->h_max_items);	memset(h->h_table, 0, h->h_max_items * sizeof(struct hash_table_item));	h->h_items = 0;		for (i = 0; i < old_max_items; i++) {		if (old_h_table[i].ht_data)			__hash_put(h, old_h_table[i].ht_key, old_h_table[i].ht_data);	}	free(old_h_table);}static inline void __lock(struct hash *h){#ifdef _REENTRANT	if (!h->h_locked || h->h_locked_thr != pthread_self())		pthread_mutex_lock(&h->h_mutex);#endif}static inline void __unlock(struct hash *h){#ifdef _REENTRANT	if (!h->h_locked || h->h_locked_thr != pthread_self())		pthread_mutex_unlock(&h->h_mutex);#endif}void *hash_get(struct hash *h, unsigned int key, void *arg){	int hv;	void *retval;	__lock(h);	if ((hv = __hash_find(h, key, arg)) >= 0)		retval = h->h_table[hv].ht_data;	else		retval = NULL;	__unlock(h);	return retval;}void *hash_remove(struct hash *h, unsigned int key, void *arg){	void *retval;	int hv;		__lock(h);	if ((hv = __hash_find(h, key, arg)) >= 0) {		retval = h->h_table[hv].ht_data;		h->h_table[hv].ht_key = 0;		h->h_table[hv].ht_data = NULL;		h->h_items--;		__hash_remap(h, __hv_next());	} else		retval = NULL;	__unlock(h);	return retval;}int hash_put(struct hash *h, unsigned int key, void *data){	int retval;		__lock(h);	if (__hash_need_space(h))		__hash_new_space(h);	if (h->h_items == h->h_max_items || !data)		retval = -1;	else		retval = 0;	__hash_put(h, key, data);	__unlock(h);	return retval;}int hash_put_check(struct hash *h, unsigned int key, void *data, void *arg){	int retval;		__lock(h);	if (__hash_need_space(h))		__hash_new_space(h);	if (h->h_items == h->h_max_items || !data)		retval = -1;	else		retval = __hash_put_check(h, key, data, arg);	__unlock(h);	return retval;}int hash_count(struct hash *h){	int retval;		__lock(h);	retval = h->h_items;	__unlock(h);	return retval;}void hash_lock(struct hash *h){#ifdef _REENTRANT	if (!h->h_locked || h->h_locked_thr != pthread_self()) {		pthread_mutex_lock(&h->h_mutex);		h->h_locked_thr = pthread_self();		h->h_locked = 1;	} else		h->h_locked++;#endif}void hash_unlock(struct hash *h){#ifdef _REENTRANT	if (--h->h_locked == 0)		pthread_mutex_unlock(&h->h_mutex);#endif}/* *  * hash_iterator *  */void hash_iter_set(struct hash_iterator *i, struct hash *h){	i->i_hash = h;	i->i_pos = 0;}void hash_iter_lock(struct hash_iterator *i){	hash_lock(i->i_hash);}void hash_iter_unlock(struct hash_iterator *i){	hash_unlock(i->i_hash);}void *hash_iter_get(struct hash_iterator *i, unsigned int *keyptr){	struct hash *h;	void *data;	void *retval;		h = i->i_hash;	__lock(h);	for ( ;i->i_pos < h->h_max_items; i->i_pos++) {		data = h->h_table[i->i_pos].ht_data;		if (data)			break;	}	if (i->i_pos < h->h_max_items && data) {		retval = data;		if (keyptr)			*keyptr = h->h_table[i->i_pos].ht_key;	} else		retval = NULL;	i->i_pos++;	__unlock(h);	return retval;}void hash_iter_end(struct hash_iterator *i){	i->i_hash = NULL;	i->i_pos = 0;}#ifdef TEST/* *  * Test *  */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <assert.h>#include <alloca.h>int MAX_ITEMS = 1000;static int verbose = 0;static int verbose_print(int level, char *format, ...){	va_list ap;	int retval;		if (verbose >= level) {		va_start(ap, format);		retval = vprintf(format, ap);		va_end(ap);		return retval;	}	return 0;}int main(int argc, char *argv[]){	struct hash h;	struct hash_iterator hi;	int i;	int *t, *t_arr;		while ((i = getopt(argc, argv, "vi:")) != -1) {		switch (i) {		    case 'v':			++verbose;			break;		    case 'i':			MAX_ITEMS = atoi(optarg);			break;		    default:			fprintf(stderr, "bad option\n");			exit(1);		}	}		assert(t_arr = malloc(MAX_ITEMS * sizeof(int)));	hash_init(&h, 100, NULL);		verbose_print(1, "start\n");	for (i = 0; i < MAX_ITEMS; i++) {		t = t_arr + i;		*t = i;		assert(hash_put(&h, i * i, t) == 0);	}	assert(MAX_ITEMS == hash_count(&h));		verbose_print(1, "\nhash get\n");	for (i = 0; i < MAX_ITEMS; i++) {		t = hash_get(&h, i * i, NULL);		assert(t);		assert(*t == i);		verbose_print(2, "%d ", *t);	}		verbose_print(1, "\niterator test\n");	hash_iter_set(&hi, &h);	while ((t = hash_iter_get(&hi, NULL)))		verbose_print(2, "%d ", *t);	hash_iter_end(&hi);		verbose_print(1, "\nremove test\n");	for (i = 0; i < MAX_ITEMS; i += 3) {		t = hash_remove(&h, i * i, NULL);		assert(t);		assert(*t == i);		verbose_print(2, "%d ", *t);	}		verbose_print(1, "\nhash_put_check test\n");	for (i = 0; i < MAX_ITEMS; i += 3) {		t = t_arr + i;		assert(hash_put_check(&h, i * i, t, NULL) == 0);		verbose_print(2, "%d ", *t);	}	for (i = 0; i < MAX_ITEMS; i += 3) {		t = t_arr + i;		assert(hash_put_check(&h, i * i, t, NULL) < 0);		verbose_print(2, "%d ", *t);	}	for (i = 0; i < MAX_ITEMS; i += 3) {		t = hash_remove(&h, i * i, NULL);		assert(t);		assert(*t == i);		verbose_print(2, "%d ", *t);	}		verbose_print(1, "\nhash get\n");	for (i = 0; i < MAX_ITEMS; i++) {		t = hash_get(&h, i * i, NULL);		if ((i % 3) == 0)			assert(t == NULL);		else {			assert(t);			assert(*t == i);			verbose_print(2, "%d ", *t);		}	}		hash_free(&h);	verbose_print(1, "\nOK\n");	return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -