N久之前写的SHA-1和SHA-256的文本和字符串消息摘要程序

来源:互联网 发布:怎样使用淘宝直通车 编辑:程序博客网 时间:2024/04/30 14:40

#include   "stdio.h"      

void   getHex(long   len,unsigned char*   tmplen); //取长度填充64bit   

void   encode(FILE   *fp_read,unsigned char   *pad,unsigned char   *final,int   padlen);

//sha1读取文件并进行摘要,结果放在final

void   encode1(int l,unsigned char*   len,unsigned char*   final,int   padlen,unsigned char*str);//sha1字符串的摘要,结果放在final

void   encode2(int l,unsigned char*   len,unsigned char*   final,int   padlen,unsigned char* str);//sha256的字符串hash

void   encode3(FILE   *fp_read,unsigned char*   len,unsigned char*   final,int   padlen);//sha256的文件hash

void   wordXOR(unsigned char*   result,unsigned char*   paraA,unsigned char*   paraB); //字异或  

void   wordADD(unsigned char*   result,unsigned char*   paraA,unsigned char*   paraB); //字模32位加  

void   wordAND(unsigned char*   result,unsigned char*   paraA,unsigned char*   paraB); //字与  

void   wordOR(unsigned char*   result,unsigned char*   paraA,unsigned char*   paraB); //字或  

void   wordROTL(unsigned char*   result,unsigned char*   paraA,int   s); //循环左移

void   wordROTR(unsigned char*   result,unsigned char*   paraA,int   s); //循环右移

void   wordSHR(unsigned char* result,unsigned char* w,int s);//字右移s

void   wordFILL(unsigned char*   result,unsigned char*   paraA); //字取反

void   wordCOPY(unsigned char*   source,unsigned char*   dest); //字复制     

void   ft(unsigned char*   paraB,unsigned char*   paraC,unsigned char*   paraD,int   t,unsigned char*   tmpT); //ft函数  

void   Maj(unsigned char* tmpT,unsigned char* paraE,unsigned char* paraF,unsigned char* paraG);//256中的Maj函数

void   CH(unsigned char* tmpT,unsigned char* paraE,unsigned char* paraF,unsigned char* paraG);//256中的CH函数

void   sigma(unsigned char* result,unsigned char* w,int i);//256中的sigma函数

void   s(unsigned char* result,unsigned char* w,int i);//256中的s函数

void   T1(unsigned char*   tmpT,unsigned char* E,unsigned char* F,unsigned char *G,unsigned char* K,unsigned char* W,unsigned char* H);//T1函数

void   T2(unsigned char* tmpT,unsigned char *A,unsigned char *B,unsigned char *C);//T2函数

void   BINARYTOCHAR(unsigned char*   final,unsigned char*   result); //输出显示

void main()

 {  

 int t,q;

 printf("  SHA-1 and SHA-256 Message Digest  ");

printf("         2007122005彭尼敏       \n");

 printf("1.SHA-1\n");

printf("2.SHA-256\n");

printf("请选择:\n");

scanf("%d",&t);

         printf("1.字符串输入\n");

         printf("2.文件输入\n");

         printf("请选择:\n");

      scanf("%d",&q);

       if (t==1&&q==1)//sha1的字符串hash

       {

       char str[64],len[64],final[160],tmpWord[2];

    char   result[500],ch;   

    long   lFileLen;   //文件长度

    int    padlen,i,l;   //填充长度

       printf("输入字符串:");

       scanf("%s",str);

       l=strlen(str);

    lFileLen=8*l;  //是总共的位数

  printf("输入内容长度:%ld bit\n",lFileLen);

  padlen=(448-lFileLen)%512; //取得padding0的长度  

  if(padlen<0)   //padlen>512

  padlen+=512;   

  getHex(lFileLen,len);   //取填充长度64bit

  encode1(l,len,final,padlen,str);

  BINARYTOCHAR(final,result); //转换摘要为ASCII字符并显示输出  

  printf("%s\n",result);  //打印

         }

       else if(t==2&&q==1)//sha256的字符串hash

       {

       char str[64],len[64],final[160],tmpWord[2];

    char   result[500],ch;   

    long   lFileLen;   //文件长度

    int    padlen,i,l;   //填充长度

       printf("输入字符串:");

       scanf("%s",str);

       l=strlen(str);

    lFileLen=8*l;  //是总共的位数

    printf("输入内容长度:%ld bit\n",lFileLen);

    padlen=(448-lFileLen)%512; //取得padding0的长度  

    if(padlen<0)   //padlen>512

    padlen+=512;   

    getHex(lFileLen,len);   //取填充长度64bit

    encode2(l,len,final,padlen,str);

    BINARYTOCHAR(final,result); //转换摘要为ASCII字符并显示输出  

    printf("%s\n",result);  //打印

       }

  else if(t==2&&q==2) //sha256的文件hash

  {

   FILE   *fp_read;   //定义两个文件指针

  char   strRead[100],len[64],final[160],tmpWord[2];   //输入文件的名字,final的长度

  char   result[500],ch;   

  long   lFileLen;   //文件长度

  int    padlen,i,l;   //填充长度

  printf("Please   enter   the   path   of   Text:");   

  scanf("%s",strRead);   

  fp_read=fopen(strRead,"rb");   //为读写打开一个二进制文件

  if(fp_read==NULL)  //"r+方式该文件应该已经存在,以便能输入数据"

  {   

  printf("Open   file   %s   Error!\n",strRead);   

  return;   

  }   

  ch=fgetc(fp_read);

  l=0;

  while(ch!=EOF)

  {

         l++;

         ch=fgetc(fp_read);

  }

  lFileLen=8*l;  //是总共的位数

  printf("输入内容长度:%ld bit\n",lFileLen);

  padlen=(448-lFileLen)%512; //取得padding0的长度  

  if(padlen<0)   //padlen>512

  padlen+=512;   

  getHex(lFileLen,len);   //取填充长度64bit

  fseek(fp_read,0L,SEEK_SET);   //指向文件开始位置

  encode3(fp_read,len,final,padlen); //摘要函数  

  BINARYTOCHAR(final,result); //转换摘要为ASCII字符并显示输出  

  printf("%s\n",result);  //打印

  fclose(fp_read);   

  }   

 else //sha1的文件hash

{

  FILE   *fp_read;   //定义两个文件指针

  char   strRead[100],len[64],final[160],tmpWord[2];   //输入文件的名字,final的长度

  char   result[500],ch;   

  long   lFileLen;   //文件长度

  int    padlen,i,l;   //填充长度

  printf("Please   enter   the   path   of   Text:");   

  scanf("%s",strRead);   

  fp_read=fopen(strRead,"rb");   //为读写打开一个二进制文件

  if(fp_read==NULL)  //"r+方式该文件应该已经存在,以便能输入数据"

  {   

  printf("Open   file   %s   Error!\n",strRead);   

  return;   

  }   

  ch=fgetc(fp_read);

  l=0;

  while(ch!=EOF)

  {

         l++;

         ch=fgetc(fp_read);

  }

  lFileLen=8*l;  //是总共的位数

  printf("输入内容长度:%ld bit\n",lFileLen);

  padlen=(448-lFileLen)%512; //取得padding0的长度  

  if(padlen<0)   //padlen>512

  padlen+=512;   

  getHex(lFileLen,len);   //取填充长度64bit

  fseek(fp_read,0L,SEEK_SET);   //指向文件开始位置

  encode(fp_read,len,final,padlen); //摘要函数  

  BINARYTOCHAR(final,result); //转换摘要为ASCII字符并显示输出  

  printf("%s\n",result);  //打印

  fclose(fp_read);   

  }   

  }



wordADD(tmpT,tmpH[0],tmpA);   

  wordCOPY(tmpT,tmpH[0]);   

  wordADD(tmpT,tmpH[1],tmpB);   

  wordCOPY(tmpT,tmpH[1]);   

  wordADD(tmpT,tmpH[2],tmpC);   

  wordCOPY(tmpT,tmpH[2]);   

  wordADD(tmpT,tmpH[3],tmpD);   

  wordCOPY(tmpT,tmpH[3]);   

  wordADD(tmpT,tmpH[4],tmpE);   

  wordCOPY(tmpT,tmpH[4]);   

  }   

  for(i=0;i<20;i++)   //就是H0H4的新值

  final[i]=tmpH[i/4][i%4];   

  }  

  void     getHex(long   len,unsigned char*   tmplen)   //取填充长度64bit

  {   

  int   cur,i;   

  for(i=0;i<8;i++)   

  tmplen[i]=0x00;   //初始化

  cur=7;   

  while(len!=0)   

  {   

  if(len%256<0)   

  {   

  tmplen[cur--]=256+len%256;   

  }

  else{   

  tmplen[cur--]=len%256;   

  }   

  len=len/256;   

  }   

  }   

   

  void   wordROTL(unsigned char*   result,unsigned char*   paraA,int   s)   //循环左移s

  {   

  int   i;   

  unsigned char   tmpResult[4];   

  if(s<8)   

  {   

  for(i=0;i<4;i++)   

  result[i]=paraA[i]<<s|paraA[(i+1)%4]>>(8-s); //左移s

  }

  else{   

  wordROTL(tmpResult,paraA,7);  

  wordROTL(result,tmpResult,s-7);  

  }   

  }   

  void   wordAND(char*   result,char*   paraA,char*   paraB)   //与运算right

  {   

  int   i;   

  for(i=0;i<4;i++)   

  result[i]=paraA[i]&paraB[i];   

  }   

  void   wordOR(char*   result,char*   paraA,char*   paraB)   //或运算right

  {   

  int   i;   

  for(i=0;i<4;i++)   

  result[i]=paraA[i]|paraB[i];   

  }   

  void   wordXOR(char*   result,char*   paraA,char*   paraB)   //异或运算right

  {   

  int   i;   

  for(i=0;i<4;i++)   

  result[i]=paraA[i]^paraB[i];   

  }   

void   wordFILL(char*   result,char*   paraA)   //取反  right

  {   

  int   i;   

  for(i=0;i<4;i++)   

  result[i]=~paraA[i];

  }   

  void   wordADD(unsigned char*   result,unsigned char*   paraA,unsigned char*   paraB)   //32位的操作系统模2 

  {   

  unsigned char   fix=0x00 ;   //定义一个字符16进制

  int   i;   

  for(i=3;i>=0;i--)   

  {

  result[i]=paraA[i]+paraB[i]+fix;   

  if(paraA[i]+paraB[i]+fix>=256)   

  fix=0x01;

  else

         fix=0x00;

  }   

  }   

  void   wordCOPY(unsigned char*   source,unsigned char*   dest)   //字复制将前面的内容复制到后面32right

  {   

  int   i;   

   

  for(i=0;i<4;i++)   

  dest[i]=source[i];  

  }  

  void   ft(unsigned char*   paraB,unsigned char*   paraC,unsigned char*   paraD,int   t,unsigned char*   tmpT)   //f的四个函数

  {   

  unsigned char   tmpI[4],tmpJ[4];   

  int i;

   

  if(t<=19)   

  {   

  wordFILL(tmpT,paraB);   //字取反B的非装入tmpT              1

  wordCOPY(tmpT,tmpI);   //字复制   tmpT的东西复制到了tmpI       1

  wordAND(tmpT,tmpI,paraD); //字与  B非和D相与得到的结果装入tmpT

  wordCOPY(tmpT,tmpI);   //字复制  tmpI=tmpT

  wordAND(tmpJ,paraB,paraC);  //字与BC相与得到的结果装入tmpJ

  wordOR(tmpT,tmpI,tmpJ);   //字或tmpT=f1

  }

  else   if(t<=39)   

  {   

  wordXOR(tmpI,paraB,paraC);   //BC异或

  wordXOR(tmpT,tmpI,paraD);   //B,C,D异或tmpT=f2

  }

  else   if(t<=59)   

  {   

  wordAND(tmpI,paraB,paraC);   //BC相与

  wordAND(tmpJ,paraB,paraD);   //BD相与

  wordOR(tmpT,tmpI,tmpJ);   //以上两个或

  wordAND(tmpI,paraC,paraD);   //CD相与

  wordOR(tmpJ,tmpI,tmpT);   //以上的再或

  wordCOPY(tmpJ,tmpT);   //tmpT=tmpJ=f3

  }

  else   if(t<=79)   

  {   

  wordXOR(tmpI,paraB,paraC);   //f2

  wordXOR(tmpT,tmpI,paraD);   

  }   

  }   

  void   BINARYTOCHAR(unsigned char*   final,unsigned char*   result)   //final文件的内容输入到result中显示出来

  {   

  int   iLow,iHigh,i,j;   //定义了四个变量

  for(i=0,j=0;i<20;i++)   

  {   

  iHigh=(final[i]&0xF0)>>4;   //先与F0做与运算,然后再右移四位得到高位

  iLow=final[i]&0x0F;   //然后再与0F做与运算 得到低位

  if(iHigh>9)   

  result[j++]=iHigh-9+0x40;   

  else   

  result[j++]=iHigh+0x30;   

  if(iLow>9)   

  result[j++]=iLow-9+0x40;   

  else   

  result[j++]=iLow+0x30;   

  }   

  result[j]='\0';   

  }


原创粉丝点击