libStatGen Software  1
Hash.cpp
00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include "Hash.h"
00019 
00020 #include <ctype.h>
00021 
00022 // ********************************************************
00023 //
00024 // This code is based on the original by Robert Jenkins.
00025 //
00026 // http://burtleburtle.net/bob/hash/doobs.html
00027 //
00028 // ********************************************************
00029 
00030 #define MIX_INTEGERS(a,b,c) \
00031     { \
00032     a -= b; a -= c; a ^= (c>>13); \
00033     b -= c; b -= a; b ^= (a<<8);  \
00034     c -= a; c -= b; c ^= (b>>13); \
00035     a -= b; a -= c; a ^= (c>>12); \
00036     b -= c; b -= a; b ^= (a<<16); \
00037     c -= a; c -= b; c ^= (b>>5);  \
00038     a -= b; a -= c; a ^= (c>>3);  \
00039     b -= c; b -= a; b ^= (a<<10); \
00040     c -= a; c -= b; c ^= (b>>15); \
00041     }
00042 
00043 #define ui   (unsigned int)
00044 
00045 unsigned int hash(const unsigned char * key, unsigned int length, unsigned int initval)
00046 {
00047     unsigned int a = 0x9e3779b9;
00048     unsigned int b = 0x9e3779b9;
00049     unsigned int c = initval;
00050     unsigned int len = length;
00051 
00052     /*---------------------------------------- handle most of the key */
00053     while (len >= 12)
00054     {
00055         a += (key[0] +(ui(key[1])<<8) +(ui(key[2])<<16) +(ui(key[3])<<24));
00056         b += (key[4] +(ui(key[5])<<8) +(ui(key[6])<<16) +(ui(key[7])<<24));
00057         c += (key[8] +(ui(key[9])<<8) +(ui(key[10])<<16)+(ui(key[11])<<24));
00058         MIX_INTEGERS(a,b,c);
00059         key += 12;
00060         len -= 12;
00061     }
00062 
00063     /*------------------------------------- handle the last 11 bytes */
00064     c += length;
00065     switch (len)             /* all the case statements fall through */
00066     {
00067         case 11:
00068             c+=(ui(key[10])<<24);
00069         case 10:
00070             c+=(ui(key[9])<<16);
00071         case 9 :
00072             c+=(ui(key[8])<<8);
00073             /* the first byte of c is reserved for the length */
00074 
00075         case 8 :
00076             b+=(ui(key[7])<<24);
00077         case 7 :
00078             b+=(ui(key[6])<<16);
00079         case 6 :
00080             b+=(ui(key[5])<<8);
00081         case 5 :
00082             b+=key[4];
00083 
00084         case 4 :
00085             a+=(ui(key[3])<<24);
00086         case 3 :
00087             a+=(ui(key[2])<<16);
00088         case 2 :
00089             a+=(ui(key[1])<<8);
00090         case 1 :
00091             a+=key[0];
00092             /* case 0: nothing left to add */
00093     }
00094     MIX_INTEGERS(a,b,c);
00095 
00096     /*-------------------------------------------- report the result */
00097     return c;
00098 }
00099 
00100 unsigned int hash_no_case(const unsigned char * key, unsigned int length, unsigned int initval)
00101 {
00102     unsigned int a = 0x9e3779b9;
00103     unsigned int b = 0x9e3779b9;
00104     unsigned int c = initval;
00105     unsigned int len = length;
00106 
00107     /*---------------------------------------- handle most of the key */
00108     while (len >= 12)
00109     {
00110         a += (toupper(key[0]) +(ui(toupper(key[1]))<<8) +(ui(toupper(key[2]))<<16) +(ui(toupper(key[3]))<<24));
00111         b += (toupper(key[4]) +(ui(toupper(key[5]))<<8) +(ui(toupper(key[6]))<<16) +(ui(toupper(key[7]))<<24));
00112         c += (toupper(key[8]) +(ui(toupper(key[9]))<<8) +(ui(toupper(key[10]))<<16)+(ui(toupper(key[11]))<<24));
00113         MIX_INTEGERS(a,b,c);
00114         key += 12;
00115         len -= 12;
00116     }
00117 
00118     /*------------------------------------- handle the last 11 bytes */
00119     c += length;
00120     switch (len)             /* all the case statements fall through */
00121     {
00122         case 11:
00123             c+=(ui(toupper(key[10]))<<24);
00124         case 10:
00125             c+=(ui(toupper(key[9]))<<16);
00126         case 9 :
00127             c+=(ui(toupper(key[8]))<<8);
00128             /* the first byte of c is reserved for the length */
00129 
00130         case 8 :
00131             b+=(ui(toupper(key[7]))<<24);
00132         case 7 :
00133             b+=(ui(toupper(key[6]))<<16);
00134         case 6 :
00135             b+=(ui(toupper(key[5]))<<8);
00136         case 5 :
00137             b+=toupper(key[4]);
00138 
00139         case 4 :
00140             a+=(ui(toupper(key[3]))<<24);
00141         case 3 :
00142             a+=(ui(toupper(key[2]))<<16);
00143         case 2 :
00144             a+=(ui(toupper(key[1]))<<8);
00145         case 1 :
00146             a+=toupper(key[0]);
00147             /* case 0: nothing left to add */
00148     }
00149     MIX_INTEGERS(a,b,c);
00150 
00151     /*-------------------------------------------- report the result */
00152     return c;
00153 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends