Hash,一般翻譯做"散列",也有直接音譯為"哈希"的,就是把任意長度的輸入(又叫做預(yù)映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉(zhuǎn)換是一種壓縮映射,也就是,散列值的空間通常遠(yuǎn)小于輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數(shù)。
溫江網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司自2013年起到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。
HASH主要用于信息安全領(lǐng)域中加密算法,它把一些不同長度的信息轉(zhuǎn)化成雜亂的128位的編碼里,叫做HASH值. 也可以說,hash就是找到一種數(shù)據(jù)內(nèi)容和數(shù)據(jù)存放地址之間的映射關(guān)系。Hash算法在信息安全方面的應(yīng)用主要體現(xiàn)在以下的3個方面:文件校驗(yàn)、數(shù)字簽名、鑒權(quán)協(xié)議
程程序?qū)崿F(xiàn)
// 說明:Hash函數(shù)(即散列函數(shù))在程序設(shè)計中的應(yīng)用目標(biāo) ------ 把一個對象通過某種轉(zhuǎn)換機(jī)制對應(yīng)到一個
//size_t類型(即unsigned long)的整型值。
// 而應(yīng)用Hash函數(shù)的領(lǐng)域主要是 hash表(應(yīng)用非常廣)、密碼等領(lǐng)域。
// 實(shí)現(xiàn)說明:
// ⑴、這里使用了函數(shù)對象以及泛型技術(shù),使得對所有類型的對象(關(guān)鍵字)都適用。
// ⑵、常用類型有對應(yīng)的偏特化,比如string、char*、各種整形等。
// ⑶、版本可擴(kuò)展,如果你對某種類型有特殊的需要,可以在后面實(shí)現(xiàn)專門化。
// ⑷、以下實(shí)現(xiàn)一般放在頭文件中,任何包含它的都可使用hash函數(shù)對象。
//------------------------------------實(shí)現(xiàn)------------------------------------------------
#include string
using std::string;
inlinesize_thash_str(const char* s)
{
unsigned long res = 0;
for (; *s; ++s)
res = 5 * res + *s;
returnsize_t(res);
}
template class Key
struct hash
{
size_toperator () (const Key k) const;
};
// 一般的對象,比如:vector queuestring ;的對象,需要強(qiáng)制轉(zhuǎn)化
template class Key
size_thashKey::operator () (const Key k) const
{
size_tres = 0;
size_tlen = sizeof(Key);
const char* p = reinterpret_castconst char*(k);
while (len--)
{
res = (res1)^*p++;
}
return res;
}
// 偏特化
template
size_thash string ::operator () (const string str) const
{
return hash_str(str.c_str());
}
typedef char* PChar;
template
size_thashPChar::operator () (const PChar s) const
{
return hash_str(s);
}
typedef const char* PCChar;
template
size_thashPCChar::operator () (const PCChar s) const
{
return hash_str(s);
}
template size_t hashchar::operator () (const char x) const { return x; }
template size_t hashunsigned char::operator () (const unsigned char x) const { return x; }
template size_t hashsigned char::operator () (const signed char x) const { return x; }
template size_t hashshort::operator () (const short x) const { return x; }
template size_t hashunsigned short::operator () (const unsigned short x) const { return x; }
template size_t hashint::operator () (const int x) const { return x; }
template size_t hashunsigned int::operator () (const unsigned int x) const { return x; }
template size_t hashlong::operator () (const long x) const { return x; }
template size_t hashunsigned long::operator () (const unsigned long x) const { return x; }
// 使用說明:
//
// ⑴、使用時首先由于是泛型,所以要加上關(guān)鍵字類型。
//
// ⑵、其次要有一個函數(shù)對象,可以臨時、局部、全局的,只要在作用域就可以。
//
// ⑶、應(yīng)用函數(shù)對象作用于對應(yīng)類型的對象。
//----------------------- hash函數(shù)使用舉例 -------------------------
#include iostream
#include vector
#include string
using namespace std;
int main()
{
vectorstring vstr⑵;
vstr[0] = "sjw";
vstr[1] = "suninf";
hashstring strhash; // 局部函數(shù)對象
cout " Hash value: " strhash(vstr[0]) endl;
cout " Hash value: " strhash(vstr[1]) endl;
cout " Hash value: " hash vectorstring () (vstr) endl;
cout " Hash value: " hashint() (100) endl; // hashint() 臨時函數(shù)對象
return 0;
}
#include stdio.h
#includemalloc.h
#includestring.h
//#include
#define HASH_LEN 50 //哈希表的長度
#define M 47
#define NAME_NO 30 //人名的個數(shù)
typedef struct NAME
{
char *py; //名字的拼音
int k; //拼音所對應(yīng)的整數(shù)
}NAME;
NAME NameList[HASH_LEN];
typedef struct hterm //哈希表
{
char *py; //名字的拼音
int k; //拼音所對應(yīng)的整數(shù)
int si; //查找長度
}HASH;
HASH HashList[HASH_LEN];
/*-----------------------姓名(結(jié)構(gòu)體數(shù)組)初始化---------------------------------*/
void InitNameList()
{ int i;
char *f;
int r,s0;
NameList[0].py="chenghongxiu";
NameList[1].py="yuanhao";
NameList[2].py="yangyang";
NameList[3].py="zhanghen";
NameList[4].py="chenghongxiu";
NameList[5].py="xiaokai";
NameList[6].py="liupeng";
NameList[7].py="shenyonghai";
NameList[8].py="chengdaoquan";
NameList[9].py="ludaoqing";
NameList[10].py="gongyunxiang";
NameList[11].py="sunzhenxing";
NameList[12].py="sunrongfei";
NameList[13].py="sunminglong";
NameList[14].py="zhanghao";
NameList[15].py="tianmiao";
NameList[16].py="yaojianzhong";
NameList[17].py="yaojianqing";
NameList[18].py="yaojianhua";
NameList[19].py="yaohaifeng";
NameList[20].py="chengyanhao";
NameList[21].py="yaoqiufeng";
NameList[22].py="qianpengcheng";
NameList[23].py="yaohaifeng";
NameList[24].py="bianyan";
NameList[25].py="linglei";
NameList[26].py="fuzhonghui";
NameList[27].py="huanhaiyan";
NameList[28].py="liudianqin";
NameList[29].py="wangbinnian";
for (i=0;iNAME_NO;i++)// *求出各個姓名的拼音所對應(yīng)的整數(shù)
{
s0=0;
f=NameList[i].py;
for (r=0;*(f+r) != '\0';r++) //方法:將字符串的各個字符所對應(yīng)的ASCII碼相加,所得的整數(shù)做為哈希表的關(guān)鍵字
s0=*(f+r)+s0;
NameList[i].k=s0;
}
}
/*-----------------------建立哈希表---------------------------------*/
void CreateHashList()
{int i;
for ( i=0; iHASH_LEN;i++)//哈希表的初始化
{
HashList[i].py="";
HashList[i].k=0;
HashList[i].si=0;
}
for (i=0; iNAME_NO;)
{
int sum=0;
int adr=(NameList[i].k) % M; //哈希函數(shù)
int d=adr;
if(HashList[adr].si==0) //如果不沖突
{
HashList[adr].k=NameList[i].k;
HashList[adr].py=NameList[i].py;
HashList[adr].si=1;
}
else //沖突
{
do
{
d=(d+((NameList[i].k))%10+1)%M; //偽散列
sum=sum+1; //查找次數(shù)加1
}while (HashList[d].k!=0);
HashList[d].k=NameList[i].k;
HashList[d].py=NameList[i].py;
HashList[d].si=sum+1;
}i++;
}
}
/*-------------------------------------查找------------------------------------*/
void FindList()
{ int r;
char name[20]={0};
int s0=0;
int sum=1;
int adr;
int d;
printf("\n\n請輸入姓名的拼音: "); //輸入姓名
scanf("%s",name);
for ( r=0;r20;r++) //求出姓名的拼音所對應(yīng)的整數(shù)(關(guān)鍵字)
s0+=name[r];
adr=s0 % M; //使用哈希函數(shù)
d=adr;
if(HashList[adr].k==s0) //分3種情況進(jìn)行判斷
printf("\n姓名:%s 關(guān)鍵字:%d 查找長度為: 1",HashList[d].py,s0);
else if (HashList[adr].k==0)
printf("無該記錄!");
else
{
int g=0;
do
{
d=(d+s0%10+1)%M; //偽散列
sum=sum+1;
if (HashList[d].k==0)
{
printf("無記錄! ");
g=1;
}
if (HashList[d].k==s0)
{
printf("\n姓名:%s 關(guān)鍵字:%d 查找長度為:%d",HashList[d].py,s0,sum);
g=1;
}
}while(g==0);
}
}
/*--------------------------------顯示哈希表----------------------------*/
void Display()
{int i;
float average=0;
printf("\n\n地址\t關(guān)鍵字\t\t搜索長度\tH(key)\t\t拼音 \n"); //顯示的格式
for( i=0; i15; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
// printf("按任意鍵繼續(xù)顯示...\n"); //由于數(shù)據(jù)比較多,所以分屏顯示(以便在Win9x/DOS下能看到所有的數(shù)據(jù))
// getch();
for( i=15; i30; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
// printf("按任意鍵繼續(xù)顯示...\n");
// getch();
for( i=30; i40; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
//printf("按任意鍵繼續(xù)顯示...\n");
//getch();
for( i=40; i50; i++)
{
printf("%d ",i);
printf("\t%d ",HashList[i].k);
printf("\t\t%d ",HashList[i].si);
printf("\t\t%d ",(HashList[i].k)%M);
printf("\t %s ",HashList[i].py);
printf("\n");
}
for (i=0;iHASH_LEN;i++)
{average+=HashList[i].si;
average/=NAME_NO;
printf("\n\n平均查找長度:ASL(%d)=%f \n\n",NAME_NO,average);
}
}
/*--------------------------------主函數(shù)----------------------------*/
void main()
{
/* ::SetConsoleTitle("哈希表操作"); //Windows API函數(shù),設(shè)置控制臺窗口的標(biāo)題
HANDLE hCon = ::GetStdHandle(STD_OUTPUT_HANDLE); //獲得標(biāo)準(zhǔn)輸出設(shè)備的句柄
::SetConsoleTextAttribute(hCon, 10|0); //設(shè)置文本顏色
*/
printf("\n------------------------哈希表的建立和查找----------------------");
InitNameList();
CreateHashList ();
while(1)
{ char ch1;
printf("\n\n");
printf(" 1. 顯示哈希表\n");
printf(" 2. 查找\n");
printf(" 3. 退出\n");
err:
scanf("%c",ch1);
if (ch1=='1')
Display();
else if (ch1=='2')
FindList();
else if (ch1=='3')
return;
else
{
printf("\n請輸入正確的選擇!");
goto err;
}
}
}
#define MaxSize 100 //定義最大哈希表長度
#define NULLKEY -1 //定義空關(guān)鍵字值
#define DELKEY -2 //定義被刪關(guān)鍵字值
typedef int KeyType; //關(guān)鍵字類型
typedef char * InfoType; //其他數(shù)據(jù)類型
typedef struct
{
KeyType key; //關(guān)鍵字域
InfoType data; //其他數(shù)據(jù)域
int count; //探查次數(shù)域
} HashData;
typedef HashData HashTable[MaxSize]; //哈希表類型
void InsertHT(HashTable ha,int n,KeyType k,int p) //將關(guān)鍵字k插入到哈希表中
{
int i,adr;
adr=k % p;
if (ha[adr].key==NULLKEY || ha[adr].key==DELKEY) //x[j]可以直接放在哈希表中
{
ha[adr].key=k;
ha[adr].count=1;
}
else //發(fā)生沖突時采用線性探查法解決沖突
{
i=1; //i記錄x[j]發(fā)生沖突的次數(shù)
do
{
adr=(adr+1) % p;
i++;
}
while (ha[adr].key!=NULLKEY ha[adr].key!=DELKEY);
ha[adr].key=k;
ha[adr].count=i;
}
n++;
}
void CreateHT(HashTable ha,KeyType x[],int n,
網(wǎng)頁標(biāo)題:c語言哈希函數(shù)的實(shí)現(xiàn) c語言實(shí)現(xiàn)哈希數(shù)據(jù)結(jié)構(gòu)
文章源于:http://jinyejixie.com/article34/dodoese.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計、做網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站改版、網(wǎng)站維護(hù)、網(wǎng)頁設(shè)計公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)