SHA-1算法c语言实现

安全哈希算法(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();
}

这里对算法验证过程做一个记录说明:

Visual Studio 2005,文件》新建》项目》Visual c++》Win32控制台应用程序,输入项目名称“SHA1”,完成;

把下载的代码贴到SHA1.cpp文件末尾,复制“int _tmain(int argc, _TCHAR* argv[])”,删除_tmain函数,替换“main()”;

编译代码,提示以下错误:

错误 2 error C3861: “strlen”: 找不到标识符 e:\devlop\sha1\sha1\sha1.cpp 43

错误 3 error C2664: “ms_len”: 不能将参数 2 从“unsigned char [64]”转换为“char []” e:\devlop\sha1\sha1\sha1.cpp 47

错误 4 error C3861: “getch”: 找不到标识符 e:\devlop\sha1\sha1\sha1.cpp 98

第一条是警告,可以不处理

警告 1 warning 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键编译项目,发现还有错误:

错误 2 error C2664: “strlen”: 不能将参数 1 从“unsigned char [64]”转换为“const char *” e:\devlop\sha1\sha1\sha1.cpp 45

双击错误2,定位到错误位置,在input前加(LPSTR)强制转换,编译,还有错误:

错误 2 error C2065: “LPSTR”: 未声明的标识符 e:\devlop\sha1\sha1\sha1.cpp 45

错误 3 error C2146: 语法错误 : 缺少“)”(在标识符“input”的前面) e:\devlop\sha1\sha1\sha1.cpp 45

错误 4 error C2059: 语法错误 : “)” e:\devlop\sha1\sha1\sha1.cpp 45

还是找不到标识符,方法一样:在“LPSTR"上单击鼠标右键》Refactor》Add Include;

再编译,又报错:

错误 4 error 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,结果一至。

修改后的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

SHA-1算法c语言实现,布布扣,bubuko.com

时间: 2024-10-16 00:36:25

SHA-1算法c语言实现的相关文章

PID算法(C语言)

/************ PID算法(C语言) ************/ #include <stdio.h> #include<math.h> struct _pid { int pv; /*integer that contains the process value*/ int sp; /*integer that contains the set point*/ float integral; float pgain; float igain; float dgain;

快速排序算法-C语言实现

注:本篇内容为翻译,之所以选择这篇进行翻译原因是该文章含有动画,能够更加直观地展示快速排序.同时,可以仔细看一下代码,代码中把结构化的思想给予了更加充分地表现.按照功能进行模块划分的思想得到了彻底地贯彻. 以下内容翻译自: http://cprogramminglanguage.net/quicksort-algorithm-c-source-code.aspx 译文: 在快速排序算法中,使用了分治策略.首先把序列分成两个子序列,递归地对子序列进行排序,直到整个序列排序结束. 步骤如下: 在序列

RSA算法C语言实现

RSA算法C语言实现 一.源文件三个rsa.h , rsa.c , main.c //rsa.h #include <stdio.h> #define MAX_NUM 63001 #define MAX_PRIME 251 //! 返回代码 #define OK 100 #define ERROR_NOEACHPRIME 101 #define ERROR_NOPUBLICKEY 102 #define ERROR_GENERROR 103 unsigned int MakePrivatedK

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

【转】A* A星 算法 C语言 实现代码

http://blog.csdn.net/shanshanpt/article/details/8977512 关于A*算法,很早就想写点什么,可是貌似天天在忙活着什么,可事实又没有做什么,真是浮躁啊!所以今晚还是来写一下总结吧! A*算法是很经典的只能启发式搜索算法,关于只能搜索算法和一般的搜索算法(例如DFS,BFS之类),在语言描述上的区别,我觉得用<代码大全>中的一句话描述的非常好:“驾驶汽车达到某人家,写成算法是:沿167号高速往南行至Puyallup,从XX出口后往山上开4.5英里

数据结构算法C语言实现(二)---2.3线性表的链式表示和实现之单链表

一.简述 [暂无] 二.头文件 1 #ifndef _2_3_part1_H_ 2 #define _2_3_part1_H_ 3 //2_3_part1.h 4 /** 5 author:zhaoyu 6 email:[email protected] 7 date:2016-6-4 8 note:realize my textbook <<数据结构(C语言版)>> 9 */ 10 //----线性表的单链表存储结构---- 11 /** 12 My Code 13 to mak

快速排序算法C语言版

快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过

数据结构算法C语言实现(六)---2.4一元多项式的表示及相加

一.简述 利用链表表示稀疏多项式,并基于之前的一些操作(编程实现上还是有所不同的)组合新的操作实现一元多项式的表示及相加. 二.ADT 1 抽象数据类型一元多项式的定义 2 ADT Polyomail{ 3 数据对象:D = {a[i]|a[i]属于TermSet, i = 1,2,3...,m,m>=0 4 TermSet中每个元素包含一个表示系数的实数和表示指数的整数} 5 数据关系 6 基本操作: 7 CreatPolyn(&P, m) 8 操作结果:输入 m 项的系数和指数,建立一元

回溯算法-C#语言解决八皇后问题的写法与优化

结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解答一万遍了,大多还是回溯法解决的. 关于回溯算法:个人理解为就是优化的穷举算法,穷举算法是指列出所有的可能情况,而回溯算法则是试探发现问题"剪枝"回退到上个节点,换一条路,能够大大提高求解效率. 具体到8皇后问题上来说,需要考虑以下几点: 1)将8个皇后定义为8行中的相对位置来标识,考虑增