當前位置:首頁 » 編程語言 » c語言中sha1簽名
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言中sha1簽名

發布時間: 2023-03-22 21:14:20

A. c語言 sha1編碼 返回二進制源碼怎麼寫

sha1函數返回的就是經過sha1演算法計算過後的值

B. 關於SHA1的幾個子函數

TabIgenerete: 表生成。
Hash_point: hash一個點
hash_to_string:hash到一卜拆巧個字串里御盯。
GetCmdLineInteger:得到命令行的一個整數型鍵。
FreeMem :釋放內存。

C. 想用一段C語言來做個性簽名,用來裝逼

unsigned int a = 2147483648;

a>>=1; //a 遠大於1

while (a-->0) //當a 趨向於0

puts("Love");



或者 這段, 這個要編譯後效果才好賣簡衫(可能因為字元編碼原因你會編譯錯誤 只要把主函數重打一遍就好咐兆了

#include<stdio.h>
#definelovefor(floatx=1.2f;x>-1.0f;x-=0.1f){for中腔(floaty=-1.5f;y<1.5f;y+=0.05f){floatz=x*x+y*y-1;putchar(z*z*z-x*x*x*y*y<0.0f?'*':'');}putchar(' ');}

intmain(){
love
}


D. 如何用C語言實現RSA演算法

RSA演算法它是第一個既能用於數據加密也能用於數字簽名的演算法。它易於理解和操作,也很流行。演算法的名字以發明者的名字
命名:Ron Rivest, Adi Shamir 和Leonard
Adleman。但RSA的安全性一直未能得到理論上的證明。它經歷了各種攻擊,至今未被完全攻破。

一、RSA演算法 :

首先, 找出三個數, p, q, r,
其中 p, q 是兩個相異的質數, r 是與 (p-1)(q-1) 互質的數
p, q, r 這三個數便是 private key

接著, 找出 m, 使得 rm == 1 mod (p-1)(q-1)
這個 m 一定存在, 因為 r 與 (p-1)(q-1) 互質, 用輾轉相除法就可以得到了
再來, 計算 n = pq
m, n 這兩個數便是 public key

編碼過程是, 若資料為 a, 將其看成是一個大整數, 假設 a < n
如果 a >= n 的話, 就將 a 表成 s 進位 (s <= n, 通常取 s = 2^t),
則每一位數均小於 n, 然後分段編碼
接下來, 計算 b == a^m mod n, (0 <= b < n),
b 就是編碼後的資料

解碼的過程是, 計算 c == b^r mod pq (0 <= c < pq),
於是乎, 解碼完畢 等會會證明 c 和 a 其實是相等的 :)

如果第三者進行竊聽時, 他會得到幾個數: m, n(=pq), b
他如果要解碼的話, 必須想辦法得到 r
所以, 他必須先對 n 作質因數分解
要防止他分解, 最有效的方法是找兩個非常的大質數 p, q,
使第三者作因數分解時發生困難
<定理>
若 p, q 是相異質數, rm == 1 mod (p-1)(q-1),
a 是任意一個正整數, b == a^m mod pq, c == b^r mod pq,
則 c == a mod pq

證明的過程, 會用到費馬小定理, 敘述如下:
m 是任一質數, n 是任一整數, 則 n^m == n mod m
(換另一句話說, 如果 n 和 m 互質, 則 n^(m-1) == 1 mod m)
運用一些基本的群論的知識, 就可以很容易地證出費馬小定理的

<證明>
因為 rm == 1 mod (p-1)(q-1), 所以 rm = k(p-1)(q-1) + 1, 其中 k 是整數
因為在 molo 中是 preserve 乘法的
(x == y mod z and u == v mod z => xu == yv mod z),
所以, c == b^r == (a^m)^r == a^(rm) == a^(k(p-1)(q-1)+1) mod pq

1. 如果 a 不是 p 的倍數, 也不是 q 的倍數時,
則 a^(p-1) == 1 mod p (費馬小定理) => a^(k(p-1)(q-1)) == 1 mod p
a^(q-1) == 1 mod q (費馬小定理) => a^(k(p-1)(q-1)) == 1 mod q
所以 p, q 均能整除 a^(k(p-1)(q-1)) - 1 => pq | a^(k(p-1)(q-1)) - 1
即 a^(k(p-1)(q-1)) == 1 mod pq
=> c == a^(k(p-1)(q-1)+1) == a mod pq

2. 如果 a 是 p 的倍數, 但不是 q 的倍數時,
則 a^(q-1) == 1 mod q (費馬小定理)
=> a^(k(p-1)(q-1)) == 1 mod q
=> c == a^(k(p-1)(q-1)+1) == a mod q
=> q | c - a
因 p | a
=> c == a^(k(p-1)(q-1)+1) == 0 mod p
=> p | c - a
所以, pq | c - a => c == a mod pq

3. 如果 a 是 q 的倍數, 但不是 p 的倍數時, 證明同上

4. 如果 a 同時是 p 和 q 的倍數時,
則 pq | a
=> c == a^(k(p-1)(q-1)+1) == 0 mod pq
=> pq | c - a
=> c == a mod pq
Q.E.D.

這個定理說明 a 經過編碼為 b 再經過解碼為 c 時, a == c mod n (n = pq)
但我們在做編碼解碼時, 限制 0 <= a < n, 0 <= c < n,
所以這就是說 a 等於 c, 所以這個過程確實能做到編碼解碼的功能

二、RSA 的安全性

RSA的安全性依賴於大數分解,但是否等同於大數分解一直未能得到理論上的證明,因為沒有證明破解
RSA就一定需要作大數分解。假設存在一種無須分解大數的演算法,那它肯定可以修改成為大數分解演算法。目前, RSA
的一些變種演算法已被證明等價於大數分解。不管怎樣,分解n是最顯然的攻擊方法。現在,人們已能分解多個十進制位的大素數。因此,模數n
必須選大一些,因具體適用情況而定。

三、RSA的速度

由於進行的都是大數計算,使得RSA最快的情況也比DES慢上倍,無論是軟體還是硬體實現。速度一直是RSA的缺陷。一般來說只用於少量數據加密。

四、RSA的選擇密文攻擊

RSA在選擇密文攻擊面前很脆弱。一般攻擊者是將某一信息作一下偽裝( Blind),讓擁有私鑰的實體簽署。然後,經過計算就可得到它所想要的信息。實際上,攻擊利用的都是同一個弱點,即存在這樣一個事實:乘冪保留了輸入的乘法結構:

( XM )^d = X^d *M^d mod n

前面已經提到,這個固有的問題來自於公鑰密碼系統的最有用的特徵--每個人都能使用公鑰。但從演算法上無法解決這一問題,主要措施有兩條:一條是採用好的公
鑰協議,保證工作過程中實體不對其他實體任意產生的信息解密,不對自己一無所知的信息簽名;另一條是決不對陌生人送來的隨機文檔簽名,簽名時首先使用
One-Way HashFunction 對文檔作HASH處理,或同時使用不同的簽名演算法。在中提到了幾種不同類型的攻擊方法。

五、RSA的公共模數攻擊

若系統中共有一個模數,只是不同的人擁有不同的e和d,系統將是危險的。最普遍的情況是同一信息用不同的公鑰加密,這些公鑰共模而且互質,那末該信息無需私鑰就可得到恢復。設P為信息明文,兩個加密密鑰為e1和e2,公共模數是n,則:

C1 = P^e1 mod n

C2 = P^e2 mod n

密碼分析者知道n、e1、e2、C1和C2,就能得到P。

因為e1和e2互質,故用Euclidean演算法能找到r和s,滿足:

r * e1 + s * e2 = 1

假設r為負數,需再用Euclidean演算法計算C1^(-1),則

( C1^(-1) )^(-r) * C2^s = P mod n

另外,還有其它幾種利用公共模數攻擊的方法。總之,如果知道給定模數的一對e和d,一是有利於攻擊者分解模數,一是有利於攻擊者計算出其它成對的e』和d』,而無需分解模數。解決辦法只有一個,那就是不要共享模數n。

RSA的小指數攻擊。 有一種提高 RSA速度的建議是使公鑰e取較小的值,這樣會使加密變得易於實現,速度有
所提高。但這樣作是不安全的,對付辦法就是e和d都取較大的值。

RSA演算法是
第一個能同時用於加密和數字簽名的演算法,也易於理解和操作。RSA是被研究得最廣泛的公鑰演算法,從提出到現在已近二十年,經歷了各種攻擊的考驗,逐漸為人
們接受,普遍認為是目前最優秀的公鑰方案之一。RSA的安全性依賴於大數的因子分解,但並沒有從理論上證明破譯RSA的難度與大數分解難度等價。即RSA
的重大缺陷是無法從理論上把握它的保密性能
如何,而且密碼學界多數人士傾向於因子分解不是NPC問題。
RSA的缺點主要有:A)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。B)分組長度太大,為保證安全性,n 至少也要 600
bits
以上,使運算代價很高,尤其是速度較慢,較對稱密碼演算法慢幾個數量級;且隨著大數分解技術的發展,這個長度還在增加,不利於數據格式的標准化。目
前,SET( Secure Electronic Transaction )協議中要求CA採用比特長的密鑰,其他實體使用比特的密鑰。

C語言實現

#include <stdio.h>
int candp(int a,int b,int c)
{ int r=1;
b=b+1;
while(b!=1)
{
r=r*a;
r=r%c;
b--;
}
printf("%d\n",r);
return r;
}
void main()
{
int p,q,e,d,m,n,t,c,r;
char s;
printf("please input the p,q: ");
scanf("%d%d",&p,&q);
n=p*q;
printf("the n is %3d\n",n);
t=(p-1)*(q-1);
printf("the t is %3d\n",t);
printf("please input the e: ");
scanf("%d",&e);
if(e<1||e>t)
{
printf("e is error,please input again: ");
scanf("%d",&e);
}
d=1;
while(((e*d)%t)!=1) d++;
printf("then caculate out that the d is %d\n",d);
printf("the cipher please input 1\n");
printf("the plain please input 2\n");
scanf("%d",&r);
switch(r)
{
case 1: printf("input the m: "); /*輸入要加密的明文數字*/
scanf("%d",&m);
c=candp(m,e,n);
printf("the cipher is %d\n",c);break;
case 2: printf("input the c: "); /*輸入要解密的密文數字*/
scanf("%d",&c);
m=candp(c,d,n);
printf("the cipher is %d\n",m);break;
}
getch();
}

E. C語言 是不是每個字元串都包含有一個【字元串結束符】

C語言薯宏里的每個字元串都包含有數蘆冊一個【字元串結束符】-- 即是「空字元」,用'\嘩鄭0'表示。

F. 下載軟體經常看到的sha值和MD5值到底是什麼意思都是校驗碼么。

1.SHA值就像人的指紋,是文件的數字指紋,是唯一的,一個文件對應一個唯一的SHA1值,一般用來確認你的文件和官方發布的是否一致.如果官方原版文件被別人做過手腳,那麼算出來的SHA1值就會不同.所以SHA1值是用來「驗明正身」的。有些居乎旅心叵測的人在官方系統光碟裡面加入木馬程序、廣告程序等,然後再放出來給人下載,如果你不檢查SHA1值就貿然安裝就中招了,可以在網上下載一個數字指紋檢驗器來計算你下載回來的win7系統文件的SHA1值,然後到微軟的MSDN去查看官方發布的SHA1值,如果兩者相等,說明你下載的文件是和官方提供的是一樣的,你可以放心的安裝了。這就是SHA1值的用處,其他地方不用SHA1值的。 操作系統的ISO文件一般可以直接刻盤安裝,不用解壓出來。為了保險起見你最好用「UltraISO」軟體打開你的ISO文件,如果顯示為「可啟動XX文件」那麼你就放心直接刻錄吧。 2. MD5 md5的全稱是message-digest algorithm 5(信息-摘要演算法),在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest開發出來,經md2、md3和md4發展而來。它的作用是讓大容量信息在用數陪肢字簽名軟體簽署私人密匙前被"壓縮"成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的大整數)。不管是md2、md4還是md5,它們都需要獲得一個隨機長度的信息並產生一個128位的信息摘要。雖然這些演算法的結構或多或少有些相似,但md2的設計與md4和md5完全不同,那是因為md2是蘆頃世為8位機器做過設計優化的,而md4和md5卻是面向32位的電腦。這三個演算法的描述和c語言源代碼在internet rfcs 1321中有詳細的描述( http://www.ietf.org/rfc/rfc1321.txt) ,這是一份最權威的文檔,由ronald l. rivest在1992年8月向ieft提交。

求採納

G. 如何使用C語言獲取文件的SHA1哈希值

有現成的SHA1演算法函數

復制過來。

然後打開文件, 讀數據森慶謹, 調用SHA1函數即可。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<errno.h>

#undefBIG_ENDIAN_HOST
typedefunsignedintu32;

/****************
*Rotatea32此基bitintegerbynbytes
*/
#ifdefined(__GNUC__)&&defined(__i386__)
staticinlineu32
rol(u32x,intn)
{
__asm__("roll%%cl,%0"
:"=r"(x)
:"0"(x),"c"(n));
returnx;
}
#else
#definerol(x,n)(((x)<<(n))|((x)>>(32-(n))))
#endif


typedefstruct{
u32h0,h1,h2,h3,h4;
u32nblocks;
unsignedcharbuf[64];
intcount;
}SHA1_CONTEXT;void
sha1_init(SHA1_CONTEXT差橘*hd)
{
hd->h0=0x67452301;
hd->h1=0xefcdab89;
hd->h2=0x98badcfe;
hd->h3=0x10325476;
hd->h4=0xc3d2e1f0;
hd->nblocks=0;
hd->count=0;
}


/****************
*-bit-words
*/
staticvoid
transform(SHA1_CONTEXT*hd,unsignedchar*data)
{
u32a,b,c,d,e,tm;
u32x[16];

/*getvaluesfromthechainingvars*/
a=hd->h0;
b=hd->h1;
c=hd->h2;
d=hd->h3;
e=hd->h4;

#ifdefBIG_ENDIAN_HOST
memcpy(x,data,64);
#else
{
inti;
unsignedchar*p2;
for(i=0,p2=(unsignedchar*)x;i<16;i++,p2+=4)
{
p2[3]=*data++;
p2[2]=*data++;
p2[1]=*data++;
p2[0]=*data++;
}
}
#endif


#defineK10x5A827999L
#defineK20x6ED9EBA1L
#defineK30x8F1BBCDCL
#defineK40xCA62C1D6L
#defineF1(x,y,z)(z^(x&(y^z)))
#defineF2(x,y,z)(x^y^z)
#defineF3(x,y,z)((x&y)|(z&(x|y)))
#defineF4(x,y,z)(x^y^z)


#defineM(i)(tm=x[i&0x0f]^x[(i-14)&0x0f]
^x[(i-8)&0x0f]^x[(i-3)&0x0f]
,(x[i&0x0f]=rol(tm,1)))

#defineR(a,b,c,d,e,f,k,m)do{e+=rol(a,5)
+f(b,c,d)
+k
+m;
b=rol(b,30);
}while(0)
R(a,b,c,d,e,F1,K1,x[0]);
R(e,a,b,c,d,F1,K1,x[1]);
R(d,e,a,b,c,F1,K1,x[2]);
R(c,d,e,a,b,F1,K1,x[3]);
R(b,c,d,e,a,F1,K1,x[4]);
R(a,b,c,d,e,F1,K1,x[5]);
R(e,a,b,c,d,F1,K1,x[6]);
R(d,e,a,b,c,F1,K1,x[7]);
R(c,d,e,a,b,F1,K1,x[8]);
R(b,c,d,e,a,F1,K1,x[9]);
R(a,b,c,d,e,F1,K1,x[10]);
R(e,a,b,c,d,F1,K1,x[11]);
R(d,e,a,b,c,F1,K1,x[12]);
R(c,d,e,a,b,F1,K1,x[13]);
R(b,c,d,e,a,F1,K1,x[14]);
R(a,b,c,d,e,F1,K1,x[15]);
R(e,a,b,c,d,F1,K1,M(16));
R(d,e,a,b,c,F1,K1,M(17));
R(c,d,e,a,b,F1,K1,M(18));
R(b,c,d,e,a,F1,K1,M(19));
R(a,b,c,d,e,F2,K2,M(20));
R(e,a,b,c,d,F2,K2,M(21));
R(d,e,a,b,c,F2,K2,M(22));
R(c,d,e,a,b,F2,K2,M(23));
R(b,c,d,e,a,F2,K2,M(24));
R(a,b,c,d,e,F2,K2,M(25));
R(e,a,b,c,d,F2,K2,M(26));
R(d,e,a,b,c,F2,K2,M(27));
R(c,d,e,a,b,F2,K2,M(28));
R(b,c,d,e,a,F2,K2,M(29));
R(a,b,c,d,e,F2,K2,M(30));
R(e,a,b,c,d,F2,K2,M(31));
R(d,e,a,b,c,F2,K2,M(32));
R(c,d,e,a,b,F2,K2,M(33));
R(b,c,d,e,a,F2,K2,M(34));
R(a,b,c,d,e,F2,K2,M(35));
R(e,a,b,c,d,F2,K2,M(36));
R(d,e,a,b,c,F2,K2,M(37));
R(c,d,e,a,b,F2,K2,M(38));
R(b,c,d,e,a,F2,K2,M(39));
R(a,b,c,d,e,F3,K3,M(40));
R(e,a,b,c,d,F3,K3,M(41));
R(d,e,a,b,c,F3,K3,M(42));
R(c,d,e,a,b,F3,K3,M(43));
R(b,c,d,e,a,F3,K3,M(44));
R(a,b,c,d,e,F3,K3,M(45));
R(e,a,b,c,d,F3,K3,M(46));
R(d,e,a,b,c,F3,K3,M(47));
R(c,d,e,a,b,F3,K3,M(48));
R(b,c,d,e,a,F3,K3,M(49));
R(a,b,c,d,e,F3,K3,M(50));
R(e,a,b,c,d,F3,K3,M(51));
R(d,e,a,b,c,F3,K3,M(52));
R(c,d,e,a,b,F3,K3,M(53));
R(b,c,d,e,a,F3,K3,M(54));
R(a,b,c,d,e,F3,K3,M(55));
R(e,a,b,c,d,F3,K3,M(56));
R(d,e,a,b,c,F3,K3,M(57));
R(c,d,e,a,b,F3,K3,M(58));
R(b,c,d,e,a,F3,K3,M(59));
R(a,b,c,d,e,F4,K4,M(60));
R(e,a,b,c,d,F4,K4,M(61));
R(d,e,a,b,c,F4,K4,M(62));
R(c,d,e,a,b,F4,K4,M(63));
R(b,c,d,e,a,F4,K4,M(64));
R(a,b,c,d,e,F4,K4,M(65));
R(e,a,b,c,d,F4,K4,M(66));
R(d,e,a,b,c,F4,K4,M(67));
R(c,d,e,a,b,F4,K4,M(68));
R(b,c,d,e,a,F4,K4,M(69));
R(a,b,c,d,e,F4,K4,M(70));
R(e,a,b,c,d,F4,K4,M(71));
R(d,e,a,b,c,F4,K4,M(72));
R(c,d,e,a,b,F4,K4,M(73));
R(b,c,d,e,a,F4,K4,M(74));
R(a,b,c,d,e,F4,K4,M(75));
R(e,a,b,c,d,F4,K4,M(76));
R(d,e,a,b,c,F4,K4,M(77));
R(c,d,e,a,b,F4,K4,M(78));
R(b,c,d,e,a,F4,K4,M(79));

/*Updatechainingvars*/
hd->h0+=a;
hd->h1+=b;
hd->h2+=c;
hd->h3+=d;
hd->h4+=e;
}


/*
*ofINBUFwithlengthINLEN.
*/
staticvoid
sha1_write(SHA1_CONTEXT*hd,unsignedchar*inbuf,size_tinlen)
{
if(hd->count==64){/*flushthebuffer*/
transform(hd,hd->buf);
hd->count=0;
hd->nblocks++;
}
if(!inbuf)
return;
if(hd->count){
for(;inlen&&hd->count<64;inlen--)
hd->buf[hd->count++]=*inbuf++;
sha1_write(hd,NULL,0);
if(!inlen)
return;
}

while(inlen>=64){
transform(hd,inbuf);
hd->count=0;
hd->nblocks++;
inlen-=64;
inbuf+=64;
}
for(;inlen&&hd->count<64;inlen--)
hd->buf[hd->count++]=*inbuf++;
}


/*
*returnsthedigest.
*,butaddingbytestothe
*.
*Returns:20bytesrepresentingthedigest.
*/

staticvoid
sha1_final(SHA1_CONTEXT*hd)
{
u32t,msb,lsb;
unsignedchar*p;

sha1_write(hd,NULL,0);/*flush*/;

t=hd->nblocks;
/*multiplyby64tomakeabytecount*/
lsb=t<<6;
msb=t>>26;
/*addthecount*/
t=lsb;
if((lsb+=hd->count)<t)
msb++;
/*multiplyby8tomakeabitcount*/
t=lsb;
lsb<<=3;
msb<<=3;
msb|=t>>29;

if(hd->count<56){/*enoughroom*/
hd->buf[hd->count++]=0x80;/*pad*/
while(hd->count<56)
hd->buf[hd->count++]=0;/*pad*/
}
else{/*needoneextrablock*/
hd->buf[hd->count++]=0x80;/*padcharacter*/
while(hd->count<64)
hd->buf[hd->count++]=0;
sha1_write(hd,NULL,0);/*flush*/;
memset(hd->buf,0,56);/*fillnextblockwithzeroes*/
}
/*appendthe64bitcount*/
hd->buf[56]=msb>>24;
hd->buf[57]=msb>>16;
hd->buf[58]=msb>>8;
hd->buf[59]=msb ;
hd->buf[60]=lsb>>24;
hd->buf[61]=lsb>>16;
hd->buf[62]=lsb>>8;
hd->buf[63]=lsb ;
transform(hd,hd->buf);

p=hd->buf;
#ifdefBIG_ENDIAN_HOST
#defineX(a)do{*(u32*)p=hd->h##a;p+=4;}while(0)
#else/*littleendian*/
#defineX(a)do{*p++=hd->h##a>>24;*p++=hd->h##a>>16;
*p++=hd->h##a>>8;*p++=hd->h##a;}while(0)
#endif
X(0);
X(1);
X(2);
X(3);
X(4);
#undefX
}

H. c語言 實現sha1演算法

你再知道裡面搜「sha1演算法」就有。void sha1_finish( sha1_context *ctx, uint8 digest[20] )函數就是你要的。

I. 用C語言寫的SHA1運行速度非常慢,大約每秒能計算300kb的數據,為什麼

for(i=0;i<strlen(message);i++)這一句可能會比較費時,如果message很大的話。
其實只要先int len = strlen(message),然後
for(i=0;i < len; i++)即可。只計算一次。

J. C語言中的hash函數

Hash,一般翻譯做"散列",也有直接音譯為"哈希"的,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列演算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小於輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。
HASH主要用於信息安全領域中加密演算法,它把一些不同長度的信息轉化成雜亂的128位的編碼里,叫做HASH值. 也可以說,hash就是找到一種數據內容和數據存放地址之間的映射關系。Hash演算法在信息安全方面的應用主要體現在以下的3個方面:文件校驗、數字簽名、鑒權協議
程程序實現
// 說明:Hash函數(即散列函數)在程序設計中的應用目標 ------ 把一個對象通過某種轉換機制對應到一個
//size_t類型(即unsigned long)的整型值。
// 而應用Hash函數的領域主要是 hash表(應用非常廣)、密碼等領域。
// 實現說明:
// ⑴、這里使用了函數對象以及泛型技術,使得對所有類型的對象(關鍵字)都適用。
// ⑵、常用類型有對應的偏特化,比如string、char*、各種整形等。
// ⑶、版本可擴展,如果你對某種類型有特殊的需要,可以在後面實現專門化。
// ⑷、以下實現一般放在頭文件中,任何包含它的都可使用hash函數對象。
//------------------------------------實現------------------------------------------------
#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< queue<string> >;的對象,需要強制轉化
template < class Key >
size_thash<Key>::operator () (const Key& k) const
{
size_tres = 0;
size_tlen = sizeof(Key);
const char* p = reinterpret_cast<const char*>(&k);
while (len--)
{
res = (res<<1)^*p++;
}
return res;
}
// 偏特化
template<>
size_thash< string >::operator () (const string& str) const
{
return hash_str(str.c_str());
}
typedef char* PChar;
template<>
size_thash<PChar>::operator () (const PChar& s) const
{
return hash_str(s);
}
typedef const char* PCChar;
template<>
size_thash<PCChar>::operator () (const PCChar& s) const
{
return hash_str(s);
}
template<> size_t hash<char>::operator () (const char& x) const { return x; }
template<> size_t hash<unsigned char>::operator () (const unsigned char& x) const { return x; }
template<> size_t hash<signed char>::operator () (const signed char& x) const { return x; }
template<> size_t hash<short>::operator () (const short& x) const { return x; }
template<> size_t hash<unsigned short>::operator () (const unsigned short& x) const { return x; }
template<> size_t hash<int>::operator () (const int& x) const { return x; }
template<> size_t hash<unsigned int>::operator () (const unsigned int& x) const { return x; }
template<> size_t hash<long>::operator () (const long& x) const { return x; }
template<> size_t hash<unsigned long>::operator () (const unsigned long& x) const { return x; }
// 使用說明:
//
// ⑴、使用時首先由於是泛型,所以要加上關鍵字類型。
//
// ⑵、其次要有一個函數對象,可以臨時、局部、全局的,只要在作用域就可以。
//
// ⑶、應用函數對象作用於對應類型的對象。
//----------------------- hash函數使用舉例 -------------------------
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> vstr⑵;
vstr[0] = "sjw";
vstr[1] = "suninf";
hash<string> strhash; // 局部函數對象
cout << " Hash value: " << strhash(vstr[0]) << endl;
cout << " Hash value: " << strhash(vstr[1]) << endl;
cout << " Hash value: " << hash< vector<string> >() (vstr) << endl;
cout << " Hash value: " << hash<int>() (100) << endl; // hash<int>() 臨時函數對象
return 0;
}