Hash.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Hash.h"
00019
00020 #include <ctype.h>
00021
00022
00023
00024
00025
00026
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
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
00064 c += length;
00065 switch (len)
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
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
00093 }
00094 MIX_INTEGERS(a,b,c);
00095
00096
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
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
00119 c += length;
00120 switch (len)
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
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
00148 }
00149 MIX_INTEGERS(a,b,c);
00150
00151
00152 return c;
00153 }