c语言实现SHA-1算法
副标题#e#
安详哈希算法(Secure Hash Algorithm)主要合用于数字签名尺度 (Digital Signature Standard DSS)内里界说的数字签名算法(Digital Signature Algorithm DSA)。对付长度小于2^64位的动静,SHA1会发生一个160位的动静摘要。当吸收到动静的时候,这个动静摘要可以用来验证数据的完整性。在传输的进程中,数据很大概会产生变革,那么这时候就会发生差异的动静摘要。 SHA1有如下特性:不行以从动静摘要中复兴信息;两个差异的动静不会发生同样的动静摘要。
算法实现的版本较量多,以下代码来自:http://download.csdn.net/detail/zhangrulzu/2936159,代码行数很少,但确实实现了想要的结果。
下载的SHA-1算法:
#include<stdio.h> void creat_w(unsigned char input[64],unsigned long w[80]) { int i,j;unsigned long temp,temp1; for(i=0;i<16;i++) { j=4*i; w[i]=((long)input[j])<<24 |((long)input[1+j])<<16|((long)input[2+j])<<8|((long)input[3+j])<<0; } for(i=16;i<80;i++) { w[i]=w[i-16]^w[i-14]^w[i-8]^w[i-3]; temp=w[i]<<1; temp1=w[i]>>31; w[i]=temp|temp1; } } char ms_len(long a,char intput[64]) { unsigned long temp3,p1; int i,j; temp3=0; p1=~(~temp3<<8); for(i=0;i<4;i++) { j=8*i; intput[63-i]=(char)((a&(p1<<j))>>j); } } main() { unsigned long H0=0x67452301,H1=0xefcdab89,H2=0x98badcfe,H3=0x10325476,H4=0xc3d2e1f0; unsigned long A,B,C,D,E,temp,temp1,temp2,temp3,k,f;int i,flag;unsigned long w[80]; unsigned char input[64]; long x;int n; printf("input message:\n"); scanf("%s",input); n=strlen(input); if(n<57) { x=n*8; ms_len(x,input); if(n==56) for(i=n;i<60;i++) input[i]=0; else { input[n]=128; for(i=n+1;i<60;i++) input[i]=0; } } creat_w(input,w); /*for(i=0;i<80;i++) printf("%lx,",w[i]);*/ printf("\n"); A=H0;B=H1;C=H2;D=H3;E=H4; for(i=0;i<80;i++) { flag=i/20; switch(flag) { case 0: k=0x5a827999;f=(B&C)|(~B&D);break; case 1: k=0x6ed9eba1;f=B^C^D;break; case 2: k=0x8f1bbcdc;f=(B&C)|(B&D)|(C&D);break; case 3: k=0xca62c1d6;f=B^C^D;break; } /*printf("%lx,%lx\n",k,f); */ temp1=A<<5; temp2=A>>27; temp3=temp1|temp2; temp=temp3+f+E+w[i]+k; E=D; D=C; temp1=B<<30; temp2=B>>2; C=temp1|temp2; B=A; A=temp; printf("%lx,%lx,%lx,%lx,%lx\n",A,B,C,D,E); } H0=H0+A; H1=H1+B; H2=H2+C; H3=H3+D; H4=H4+E; printf("\noutput hash value:\n"); printf("%lx,%lx,%lx,%lx,%lx",H0,H1,H2,H3,H4); getch(); }
#p#副标题#e#
这里对算法验证进程做一个记录说明:
Visual Studio 2005,文件》新建》项目》Visual c++》Win32节制台应用措施,输入项目名称“SHA1”,完成;
把下载的代码贴到SHA1.cpp文件末端,复制“int _tmain(int argc, _TCHAR* argv[])”,删除_tmain函数,替换“main()”;
编译代码,提示以下错误:
错误2error C3861: “strlen”: 找不到标识符e:\devlop\sha1\sha1\sha1.cpp 43
错误3error C2664: “ms_len”: 不能将参数 2 从“unsigned char [64]”转换为“char []”e:\devlop\sha1\sha1\sha1.cpp 47
错误4error C3861: “getch”: 找不到标识符e:\devlop\sha1\sha1\sha1.cpp 98
第一条是告诫,可以不处理惩罚
告诫1warning C4996: ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.e:\devlop\sha1\sha1\sha1.cpp 42
双击错误2,定位到错误位置,在“strlen"上单击鼠标右键》Refactor》Add Include,如下图:
假如没有这一项,那应该是没有安装VC助手的原因;
双击错误3,定位到错误位置,在变量input前加(char*)强制转换;
双击错误4,定位到错误位置,在“getch"上单击鼠标右键》Refactor》Add Include;
按F6键编译项目,发明尚有错误:
错误2error C2664: “strlen”: 不能将参数 1 从“unsigned char [64]”转换为“const char *”e:\devlop\sha1\sha1\sha1.cpp 45
双击错误2,定位到错误位置,在input前加(LPSTR)强制转换,编译,尚有错误:
错误2error C2065: “LPSTR”: 未声明的标识符e:\devlop\sha1\sha1\sha1.cpp 45
错误3error C2146: 语法错误 : 缺少“)”(在标识符“input”的前面)e:\devlop\sha1\sha1\sha1.cpp 45
错误4error C2059: 语法错误 : “)”e:\devlop\sha1\sha1\sha1.cpp 45
照旧找不到标识符,要领一样:在“LPSTR"上单击鼠标右键》Refactor》Add Include;
再编译,又报错:
错误4error C4716: “ms_len”: 必需返回一个值e:\devlop\sha1\sha1\sha1.cpp 38
定位到错误位置,仔细看了一下,这个函数的返回值应该没什么用,随便返回一个:return ‘0’;
再编译,OK,终于生成乐成了!
F5调试,输入:abcd,回车,哦,输出了许多几何东东,查察代码的输出挪用,
找到92行应该没用,注释://printf("%lx,%lx,%lx,%lx,%lx\n",A,B,C,D,E);//输出编码进程,
最后获得的SHA1哈希值中尚有逗号,找到100行,将printf("%lx,%lx,%lx,%lx,%lx",H0,H1,H2,H3,H4);名目化字符串中的逗号去掉;
再编译,F5调试,输入:abcd,回车,功效如下图:
获得的功效对差池呢,找到一个在线SHA1加密东西,输入abcd,功效如下:
比拟一下,OK,功效一至。
#p#分页标题#e#
修改后的SHA-1算法:
// SHA1.cpp : 界说节制台应用措施的进口点。 // #include "stdafx.h" #include<stdio.h> #include <string.h> #include <conio.h> #include <wtypes.h> void creat_w(unsigned char input[64],unsigned long w[80]) { int i,j;unsigned long temp,temp1; for(i=0;i<16;i++) { j=4*i; w[i]=((long)input[j])<<24 |((long)input[1+j])<<16|((long)input[2+j])<<8|((long)input[3+j])<<0; } for(i=16;i<80;i++) { w[i]=w[i-16]^w[i-14]^w[i-8]^w[i-3]; temp=w[i]<<1; temp1=w[i]>>31; w[i]=temp|temp1; } } char ms_len(long a,char intput[64]) { unsigned long temp3,p1; int i,j; temp3=0; p1=~(~temp3<<8); for(i=0;i<4;i++) { j=8*i; intput[63-i]=(char)((a&(p1<<j))>>j); } return '0'; } int _tmain(int argc, _TCHAR* argv[]) { unsigned long H0=0x67452301,H1=0xefcdab89,H2=0x98badcfe,H3=0x10325476,H4=0xc3d2e1f0; unsigned long A,B,C,D,E,temp,temp1,temp2,temp3,k,f;int i,flag;unsigned long w[80]; unsigned char input[64]; long x;int n; printf("input message:\n"); scanf("%s",input); n=strlen((LPSTR)input); if(n<57) { x=n*8; ms_len(x,(char*)input); if(n==56) for(i=n;i<60;i++) input[i]=0; else { input[n]=128; for(i=n+1;i<60;i++) input[i]=0; } } creat_w(input,w); /*for(i=0;i<80;i++) printf("%lx,",w[i]);*/ printf("\n"); A=H0;B=H1;C=H2;D=H3;E=H4; for(i=0;i<80;i++) { flag=i/20; switch(flag) { case 0: k=0x5a827999;f=(B&C)|(~B&D);break; case 1: k=0x6ed9eba1;f=B^C^D;break; case 2: k=0x8f1bbcdc;f=(B&C)|(B&D)|(C&D);break; case 3: k=0xca62c1d6;f=B^C^D;break; } /*printf("%lx,%lx\n",k,f); */ temp1=A<<5; temp2=A>>27; temp3=temp1|temp2; temp=temp3+f+E+w[i]+k; E=D; D=C; temp1=B<<30; temp2=B>>2; C=temp1|temp2; B=A; A=temp; //printf("%lx,%lx,%lx,%lx,%lx\n",A,B,C,D,E);//输出编码进程 } H0=H0+A; H1=H1+B; H2=H2+C; H3=H3+D; H4=H4+E; printf("\noutput hash value:\n"); printf("%lx%lx%lx%lx%lx",H0,H1,H2,H3,H4); getch(); }
修改后项目源码下载:http://download.csdn.net/detail/testcs_dn/7344003