Annotation of embedaddon/php/ext/hash/hash_fnv.c, revision 1.1.1.2
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.2 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Author: Michael Maclean <mgdm@php.net> |
16: +----------------------------------------------------------------------+
17: */
18:
19: /* $Id$ */
20:
21: /* Based on the public domain algorithm found at
22: http://www.isthe.com/chongo/tech/comp/fnv/index.html */
23:
24: #include "php_hash.h"
25: #include "php_hash_fnv.h"
26:
27: const php_hash_ops php_hash_fnv132_ops = {
28: (php_hash_init_func_t) PHP_FNV132Init,
29: (php_hash_update_func_t) PHP_FNV132Update,
30: (php_hash_final_func_t) PHP_FNV132Final,
31: (php_hash_copy_func_t) php_hash_copy,
32: 4,
33: 4,
34: sizeof(PHP_FNV132_CTX)
35: };
36:
37: const php_hash_ops php_hash_fnv1a32_ops = {
38: (php_hash_init_func_t) PHP_FNV132Init,
39: (php_hash_update_func_t) PHP_FNV1a32Update,
40: (php_hash_final_func_t) PHP_FNV132Final,
41: (php_hash_copy_func_t) php_hash_copy,
42: 4,
43: 4,
44: sizeof(PHP_FNV132_CTX)
45: };
46:
47: const php_hash_ops php_hash_fnv164_ops = {
48: (php_hash_init_func_t) PHP_FNV164Init,
49: (php_hash_update_func_t) PHP_FNV164Update,
50: (php_hash_final_func_t) PHP_FNV164Final,
51: (php_hash_copy_func_t) php_hash_copy,
52: 8,
53: 4,
54: sizeof(PHP_FNV164_CTX)
55: };
56:
57: const php_hash_ops php_hash_fnv1a64_ops = {
58: (php_hash_init_func_t) PHP_FNV164Init,
59: (php_hash_update_func_t) PHP_FNV1a64Update,
60: (php_hash_final_func_t) PHP_FNV164Final,
61: (php_hash_copy_func_t) php_hash_copy,
62: 8,
63: 4,
64: sizeof(PHP_FNV164_CTX)
65: };
66:
67: /* {{{ PHP_FNV132Init
68: * 32-bit FNV-1 hash initialisation
69: */
70: PHP_HASH_API void PHP_FNV132Init(PHP_FNV132_CTX *context)
71: {
72: context->state = PHP_FNV1_32_INIT;
73: }
74: /* }}} */
75:
76: PHP_HASH_API void PHP_FNV132Update(PHP_FNV132_CTX *context, const unsigned char *input,
77: unsigned int inputLen)
78: {
79: context->state = fnv_32_buf((void *)input, inputLen, context->state, 0);
80: }
81:
82: PHP_HASH_API void PHP_FNV1a32Update(PHP_FNV132_CTX *context, const unsigned char *input,
83: unsigned int inputLen)
84: {
85: context->state = fnv_32_buf((void *)input, inputLen, context->state, 1);
86: }
87:
88: PHP_HASH_API void PHP_FNV132Final(unsigned char digest[4], PHP_FNV132_CTX * context)
89: {
90: #ifdef WORDS_BIGENDIAN
91: memcpy(digest, &context->state, 4);
92: #else
93: int i = 0;
94: unsigned char *c = (unsigned char *) &context->state;
95:
96: for (i = 0; i < 4; i++) {
97: digest[i] = c[3 - i];
98: }
99: #endif
100: }
101:
102: /* {{{ PHP_FNV164Init
103: * 64-bit FNV-1 hash initialisation
104: */
105: PHP_HASH_API void PHP_FNV164Init(PHP_FNV164_CTX *context)
106: {
107: context->state = PHP_FNV1_64_INIT;
108: }
109: /* }}} */
110:
111: PHP_HASH_API void PHP_FNV164Update(PHP_FNV164_CTX *context, const unsigned char *input,
112: unsigned int inputLen)
113: {
114: context->state = fnv_64_buf((void *)input, inputLen, context->state, 0);
115: }
116:
117: PHP_HASH_API void PHP_FNV1a64Update(PHP_FNV164_CTX *context, const unsigned char *input,
118: unsigned int inputLen)
119: {
120: context->state = fnv_64_buf((void *)input, inputLen, context->state, 1);
121: }
122:
123: PHP_HASH_API void PHP_FNV164Final(unsigned char digest[8], PHP_FNV164_CTX * context)
124: {
125: #ifdef WORDS_BIGENDIAN
126: memcpy(digest, &context->state, 8);
127: #else
128: int i = 0;
129: unsigned char *c = (unsigned char *) &context->state;
130:
131: for (i = 0; i < 8; i++) {
132: digest[i] = c[7 - i];
133: }
134: #endif
135: }
136:
137:
138: /*
139: * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer
140: *
141: * input:
142: * buf - start of buffer to hash
143: * len - length of buffer in octets
144: * hval - previous hash value or 0 if first call
145: * alternate - if > 0 use the alternate version
146: *
147: * returns:
148: * 32 bit hash as a static hash type
149: */
150: static php_hash_uint32
151: fnv_32_buf(void *buf, size_t len, php_hash_uint32 hval, int alternate)
152: {
153: unsigned char *bp = (unsigned char *)buf; /* start of buffer */
154: unsigned char *be = bp + len; /* beyond end of buffer */
155:
156: /*
157: * FNV-1 hash each octet in the buffer
158: */
159: while (bp < be) {
160:
161: if (alternate == 0) {
162: /* multiply by the 32 bit FNV magic prime mod 2^32 */
163: hval *= PHP_FNV_32_PRIME;
164:
165: /* xor the bottom with the current octet */
166: hval ^= (php_hash_uint32)*bp++;
167: } else {
168: /* xor the bottom with the current octet */
169: hval ^= (php_hash_uint32)*bp++;
170:
171: /* multiply by the 32 bit FNV magic prime mod 2^32 */
172: hval *= PHP_FNV_32_PRIME;
173: }
174: }
175:
176: /* return our new hash value */
177: return hval;
178: }
179:
180: /*
181: * fnv_64_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer
182: *
183: * input:
184: * buf - start of buffer to hash
185: * len - length of buffer in octets
186: * hval - previous hash value or 0 if first call
187: * alternate - if > 0 use the alternate version
188: *
189: * returns:
190: * 64 bit hash as a static hash type
191: */
192: static php_hash_uint64
193: fnv_64_buf(void *buf, size_t len, php_hash_uint64 hval, int alternate)
194: {
195: unsigned char *bp = (unsigned char *)buf; /* start of buffer */
196: unsigned char *be = bp + len; /* beyond end of buffer */
197:
198: /*
199: * FNV-1 hash each octet of the buffer
200: */
201: while (bp < be) {
202:
203: if (alternate == 0) {
204: /* multiply by the 64 bit FNV magic prime mod 2^64 */
205: hval *= PHP_FNV_64_PRIME;
206:
207: /* xor the bottom with the current octet */
208: hval ^= (php_hash_uint64)*bp++;
209: } else {
210: /* xor the bottom with the current octet */
211: hval ^= (php_hash_uint64)*bp++;
212:
213: /* multiply by the 64 bit FNV magic prime mod 2^64 */
214: hval *= PHP_FNV_64_PRIME;
215: }
216: }
217:
218: /* return our new hash value */
219: return hval;
220: }
221:
222: /*
223: * Local variables:
224: * tab-width: 4
225: * c-basic-offset: 4
226: * End:
227: * vim600: noet sw=4 ts=4 fdm=marker
228: * vim<600: noet sw=4 ts=4
229: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>