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

📄 hash.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hash - one-way hash routines * * Copyright (C) 1999-2006  Landon Curt Noll * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL.  You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA. * * @(#) $Revision: 29.10 $ * @(#) $Id: hash.c,v 29.10 2006/06/20 10:25:45 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/hash.c,v $ * * Under source code control:	1995/11/23 05:13:11 * File existed as early as:	1995 * * chongo <was here> /\oo/\	http://www.isthe.com/chongo/ * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/ */#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include "calc.h"#include "value.h"#include "zrand.h"#include "zrandom.h"#include "hash.h"/* * external hash_setup functions */extern void shs_init_state(HASH*);extern void shs1_init_state(HASH*);extern void MD5_init_state(HASH*);/* * hash_long can deal with BOOL's, int's, FLAGS's and LEN's */#define hash_bool(type, val, state) (hash_long((type), (long)(val), (state)))#define hash_int(type, val, state) (hash_long((type), (long)(val), (state)))#define hash_flag(type, val, state) (hash_long((type), (long)(val), (state)))#define hash_len(type, val, state) (hash_long((type), (long)(val), (state)))/* * hash_setup - setup the hash state for a given hash */static struct hash_setup {	int type;		/* hash type (see XYZ_HASH_TYPE below) */	void (*init_state)(HASH*);	/* initialize a hash state */} htbl[] = {	{ SHS_HASH_TYPE, shs_init_state },	/* old SHS / SHA */	{ SHS1_HASH_TYPE, shs1_init_state },	/* SHS-1 / SHA-1 */	{ MD5_HASH_TYPE, MD5_init_state },	/* MD5 */	{ -1, NULL }		/* must be last */};/* * hash_init - initialize a hash state * * given: *	type	- hash type (see hash.h) *	state	- the state to initialize, or NULL to malloc it * * returns: *	initialized state */HASH *hash_init(int type, HASH *state){	int i;	/*	 * malloc if needed	 */	if (state == NULL) {		state = (HASH *)malloc(sizeof(HASH));		if (state == NULL) {			math_error("hash_init: cannot malloc HASH");			/*NOTREACHED*/		}	}	/*	 * clear hash value	 */	memset((void*)state, 0, sizeof(HASH));	state->bytes = TRUE;	/*	 * search for the hash_setup function	 */	for (i=0; htbl[i].init_state != NULL; ++i) {		/* if we found the state that we were looking for */		if (type == htbl[i].type) {			/* initialize state and return */			(htbl[i].init_state)(state);			/* firewall - MAX_CHUNKSIZE must be >= chunksize */			if (state->chunksize > MAX_CHUNKSIZE) {				math_error(				  "internal error: MAX_CHUNKSIZE is too small");				/*NOTREACHED*/			}			return state;		}	}	/*	 * no such hash state	 */	math_error("internal error: hash type not found in htbl[]");	return NULL;}/* * hash_free - free the hash state */voidhash_free(HASH *state){	/*	 * do nothing if state is NULL	 */	if (state == NULL) {		return;	}	/*	 * free main state and return	 */	free(state);	return;}/* * hash_copy - copy a hash state * * given: *	state	- the state to copy * * returns: *	pointer to copy of state */HASH *hash_copy(HASH *state){	HASH *hnew;		/* copy of state */	/*	 * malloc new state	 */	hnew = (HASH *)malloc(sizeof(HASH));	if (hnew == NULL) {		math_error("hash_init: cannot malloc HASH");		/*NOTREACHED*/	}	/*	 * duplicate state	 */	memcpy((void *)hnew, (void *)state, sizeof(HASH));	return hnew;}/* * hash_cmp - compare hash values * * given: *	a	first hash state *	b	second hash state * * returns: *	TRUE => hash states are different *	FALSE => hash states are the same */inthash_cmp(HASH *a, HASH *b){	/*	 * firewall and quick check	 */	if (a == b) {		/* pointers to the same object */		return FALSE;	}	if (a == NULL || b == NULL) {		/* one pointer is NULL, so they differ */		return TRUE;	}	if (a->cmp == NULL || b->cmp == NULL) {		/* one cmp function is NULL, so they differ */		return TRUE;	}	/*	 * compare hash types	 */	if (a->hashtype != b->hashtype) {		/* different hash types are different */		return TRUE;	}	/*	 * perform the hash specific comparison	 */	return ((a->cmp)(a,b));}/* * hash_print - print the name and value of a hash * * given: *	state	the hash state to print name and value of */voidhash_print(HASH *state){	/* print the hash */	(state->print)(state);	return;}/* * hash_final - finalize the state of a hash and return a ZVALUE * * given: *	state	the hash state to finalize * * returns: *	hash state as a ZVALUE */ZVALUEhash_final(HASH *state){	/* return the finalized the hash value */	return (state->final)(state);}/* * hash_long - note a long value * * given: *	type	- hash type (see hash.h) *	longval - a long value *	state	- the state to hash * * returns: *	the new state * * This function will hash a long value as if it were a 64 bit value. * The input is a long.	 If a long is smaller than 64 bits, we will * hash a final 32 bits of zeros. * * This function is OK to hash BOOL's, unslogned long's, unsigned int's * signed int's as well as FLAG's and LEN's. */HASH *hash_long(int type, long longval, HASH *state){	long lval[64/LONG_BITS];	/* 64 bits of longs */	/*	 * initialize if state is NULL	 */	if (state == NULL) {		state = hash_init(type, NULL);	}	/*	 * setup for the hash_long	 */	(state->chkpt)(state);	state->bytes = FALSE;	/* data to be read as words */	/*	 * catch the zero numeric value special case	 */	if (longval == 0) {		/* note a zero numeric value and return */		(state->note)(HASH_ZERO(state->base), state);		return state;	}	/*	 * prep for a long value hash	 */	(state->note)(state->base, state);	/*	 * hash as if we have a 64 bit value	 */	memset((char *)lval, 0, sizeof(lval));	lval[0] = longval;	(state->update)(state, (USB8 *)lval, sizeof(lval));	/*	 * all done	 */	return state;}/* * hash_zvalue - hash a ZVALUE * * given: *	type	- hash type (see hash.h) *	zval	- the ZVALUE *	state	- the state to hash or NULL * * returns: *	the new state */HASH *hash_zvalue(int type, ZVALUE zval, HASH *state){#if CALC_BYTE_ORDER == BIG_ENDIAN && BASEB == 16	int full_lim;		/* HALFs in whole chunks in zval */	int chunkhalf;		/* size of half buffer in HALFs */	int i;	int j;#endif#if BASEB == 16	HALF half[MAX_CHUNKSIZE];	/* For endian reversal */#endif	/*	 * initialize if state is NULL	 */	if (state == NULL) {		state = hash_init(type, NULL);	}	/*	 * setup for the ZVALUE hash	 */	(state->chkpt)(state);	state->bytes = FALSE;	/* data to be read as words */	/*	 * catch the zero numeric value special case	 */	if (ziszero(zval)) {		/* note a zero numeric value and return */		(state->note)(HASH_ZERO(state->base), state);		return state;	}	/*	 * prep for a ZVALUE hash	 */	(state->note)(HASH_ZVALUE(state->base), state);	/* note if we have a negative value */	if (zisneg(zval)) {		(state->note)(HASH_NEG(state->base), state);	}#if CALC_BYTE_ORDER == BIG_ENDIAN && BASEB == 16	/*	 * hash full chunks	 *	 * We need to convert the array of HALFs into canonical architectural	 * independent form -- 32 bit arrays.  Because we have 16 bit values	 * in Big Endian form, we need to swap 16 bit values so that they	 * appear as 32 bit Big Endian values.	 */	chunkhalf = state->chunksize/sizeof(HALF);	full_lim = (zval.len / chunkhalf) * chunkhalf;	for (i=0; i < full_lim; i += chunkhalf) {		/* HALF swap copy a chunk into a data buffer */		for (j=0; j < chunkhalf; j += 2) {			half[j] = zval.v[i+j+1];			half[j+1] = zval.v[i+j];		}		(state->update)(state, (USB8*) half, state->chunksize);	}	/*	 * hash the final partial chunk (if any)	 *	 * We need to convert the array of HALFs into canonical architectural	 * independent form -- 32 bit arrays.  Because we have 16 bit values	 * in Big Endian form, we need to swap 16 bit values so that they	 * appear as 32 bit Big Endian values.	 */	if (zval.len > full_lim) {		for (j=0; j < zval.len-full_lim-1; j += 2) {			half[j] = zval.v[full_lim+j+1];			half[j+1] = zval.v[full_lim+j];		}		if (j < zval.len-full_lim) {			half[j] = (HALF)0;			half[j+1] = zval.v[zval.len-1];			--full_lim;		}		(state->update)(state, (USB8 *) half,			  (zval.len-full_lim)*sizeof(HALF));	}#else	/*	 * hash the array of HALFs	 *	 * The array of HALFs is equivalent to the canonical architectural	 * independent form.  We either have 32 bit HALFs (in which case	 * we do not case the byte order) or we have 16 bit HALFs in Little	 * Endian order (which happens to be laid out in the same order as	 * 32 bit values).	 */	(state->update)(state, (USB8 *)zval.v, zval.len*sizeof(HALF));#if BASEB == 16	if (zval.len & 1) {		/* padding to complete word */		half[0] = 0;		(state->update)(state, (USB8 *) half, 2);	}#endif#endif	/*	 * all done	 */	return state;}/* * hash_number - hash a NUMBER * * given: *	type	- hash type (see hash.h) *	n	- the NUMBER *	state	- the state to hash or NULL * * returns: *	the new state */HASH *hash_number(int type, void *n, HASH *state){	NUMBER *number = (NUMBER *)n;	/* n as a NUMBER pointer */	BOOL sign;			/* sign of the denominator */	/*	 * initialize if state is NULL	 */	if (state == NULL) {		state = hash_init(type, NULL);	}	/*	 * setup for the NUMBER hash	 */	(state->chkpt)(state);	state->bytes = FALSE;	/*	 * process the numerator	 */	state = hash_zvalue(type, number->num, state);	/*	 * if the NUMBER is not an integer, process the denominator	 */	if (qisfrac(number)) {		/* note the division */		(state->note)(HASH_DIV(state->base), state);		/* hash denominator as positive -- just in case */		sign = number->den.sign;		number->den.sign = 0;		/* hash the denominator */		state = hash_zvalue(type, number->den, state);		/* restore the sign */		number->den.sign = sign;	}	/*	 * all done	 */	return state;}/* * hash_complex - hash a COMPLEX * * given: *	type	- hash type (see hash.h) *	c	- the COMPLEX *	state	- the state to hash or NULL * * returns: *	the new state */

⌨️ 快捷键说明

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