root/ext/hash/hash_fnv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_FNV132Init
  2. PHP_FNV132Update
  3. PHP_FNV1a32Update
  4. PHP_FNV132Final
  5. PHP_FNV164Init
  6. PHP_FNV164Update
  7. PHP_FNV1a64Update
  8. PHP_FNV164Final
  9. fnv_32_buf
  10. fnv_64_buf

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 7                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 The PHP Group                                |
   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  */

/* [<][>][^][v][top][bottom][index][help] */