libStatGen Software
1
|
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 }