具體流程就是建立一個較大的數組,而後經過特定的算法,將字符串轉成整數,而後存入到這個數組中,而後能夠經過取模,得到這個string在數組中的下標。算法
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAXMPQHASHTABLELEN 8192 typedef struct { long nHashA; long nHashB; unsigned int bExists; }MPQHASHTABLE; unsigned long cryptTable[0x500]; unsigned long HashString(char *lpszString, unsigned long dwHashType); unsigned int MPQHashTableInit(char **ppHashTable, long nTableLength); void MPQHashTableFree(char *pHashTable); unsigned int MPQHashTableAdd(char *lpszString, char *pHashTable); long MPQHashTableIsExist(char *lpszString, char *pHashTable); static void InitCryptTable() { unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i; for (index1 = 0; index1 < 0x100; index1++) { for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100) { unsigned long temp1, temp2; seed = (seed * 125 + 3) % 0x2AAAAB; temp1 = (seed & 0xFFFF) << 0x10; seed = (seed * 125 + 3) % 0x2AAAAB; temp2 = (seed & 0xFFFF); cryptTable[index2] = (temp1 | temp2); } } } /* 函數名:HashString 功能:計算字符串的哈希值 參數:lpszString:字符串的地址 dwHashType:哈希值類型 dwHashType = 0時計算的哈希值用於肯定字符串在哈希表中的位置; dwHashType = 1,dwHashType = 2時計算的哈希值用於驗證字符串 返回值:字符串的哈希值 */ unsigned long HashString(char *lpszString, unsigned long dwHashType) { unsigned char *key = (unsigned char *)lpszString; unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE; int ch; while(*key != 0) { ch = toupper(*key++); seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2); seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; } return seed1; } /* 函數名:MPQHashTableInit 功能:初始化哈希表 參數:*ppHashTable:返回分配的哈希表的地址 nTableLength:哈希表的長度 返回值:0:失敗 1:成功 */ unsigned int MPQHashTableInit(char **ppHashTable, long nTableLength) { long i = 0; char *p = NULL; MPQHASHTABLE *_pHashTable = NULL; InitCryptTable(); p = malloc(nTableLength * sizeof(MPQHASHTABLE)); if (p == NULL) { printf("%s, %d: malloc failed!\n", __FUNCTION__, __LINE__); return 0; } *ppHashTable = p; _pHashTable = (MPQHASHTABLE *)p; for (i = 0; i < nTableLength; i++) { (_pHashTable + i)->nHashA = -1; (_pHashTable + i)->nHashB = -1; (_pHashTable + i)->bExists = 0; } return 1; } /* 函數名:MPQHashTableFree 功能:釋放哈希表 參數:pHashTable:哈希表的地址 返回值:無 */ void MPQHashTableFree(char *pHashTable) { if (pHashTable != NULL) { free(pHashTable); pHashTable = NULL; } } /* 函數名:MPQHashTableAdd 功能:將字符串的信息加入哈希表 參數:lpszString:字符串的地址 pHashTable:哈希表的地址 返回值:0:失敗 1:成功 */ unsigned int MPQHashTableAdd(char *lpszString, char *pHashTable) { const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2; unsigned long nHash = HashString(lpszString, HASH_OFFSET); unsigned long nHashA = HashString(lpszString, HASH_A); unsigned long nHashB = HashString(lpszString, HASH_B); unsigned long nHashStart = nHash % MAXMPQHASHTABLELEN; unsigned long nHashPos = nHashStart; MPQHASHTABLE *_pHashTable = (MPQHASHTABLE *)pHashTable; while ((_pHashTable + nHashPos)->bExists) { nHashPos = (nHashPos + 1) % MAXMPQHASHTABLELEN; if (nHashPos == nHashStart) { return 0; } } (_pHashTable + nHashPos)->nHashA = nHashA; (_pHashTable + nHashPos)->nHashB = nHashB; (_pHashTable + nHashPos)->bExists = 1; return 1; } /* 函數名:MPQHashTableIsExist 功能:判斷某字符串在哈希表中是否存在 參數:lpszString:字符串的地址 pHashTable:哈希表的地址 返回值:-1:不存在 nHashPos 該字符串在哈希表中的索引值 */ long MPQHashTableIsExist(char *lpszString, char *pHashTable) { const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2; unsigned long nHash = HashString(lpszString, HASH_OFFSET); unsigned long nHashA = HashString(lpszString, HASH_A); unsigned long nHashB = HashString(lpszString, HASH_B); unsigned long nHashStart = nHash % MAXMPQHASHTABLELEN; unsigned long nHashPos = nHashStart; MPQHASHTABLE *_pHashTable = (MPQHASHTABLE *)pHashTable; while ((_pHashTable + nHashPos)->bExists) { if (((_pHashTable + nHashPos)->nHashA == nHashA) && ((_pHashTable + nHashPos)->nHashB == nHashB)) { return nHashPos; } else { nHashPos = (nHashPos +1) % MAXMPQHASHTABLELEN; } if (nHashPos == nHashStart) { break; } } return -1; } int main(int argc,char ** argv) { char* htable; MPQHashTableInit(&htable,MAXMPQHASHTABLELEN); //初始化hash表 for(int i=0;i<argc;++i) { MPQHashTableAdd(argv[i],htable); //向hash表裏面添加內容 } printf("%ld\n",MPQHashTableIsExist("xxxxxxxx",htable)); printf("%ld\n",MPQHashTableIsExist("k123",htable)); printf("%ld\n",MPQHashTableIsExist("k_123",htable)); printf("%ld\n",MPQHashTableIsExist("123k",htable)); return 1; }