📄 sha.c
字号:
/*a C program for the "SHA-1"Use "SHA-1" to compute the digest for the file "a.txt" in current directory created by yaolei2005-4-13*/#include "sha.h"
#include <stdio.h>#include <string.h>/*********************************Global var used to save the digest*//*state[0] = A, state[1] = B, state[2] = C, state[3] = D, state[4] = E*/unsigned int state[5];/*********************************Define the function used in SHA-1*/unsigned int f1(unsigned int B, unsigned int C, unsigned int D){ return (B&C)|(~B&D);}unsigned int f2(unsigned int B, unsigned int C, unsigned int D){ return B^C^D;}unsigned int f3(unsigned int B, unsigned int C, unsigned int D){ return (B&C)|(B&D)|(C&D);}unsigned int f4(unsigned int B, unsigned int C, unsigned int D){ return B^C^D;}/*********************************Init the global var unsigned int state[5]*/void Init(){ state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; state[4] = 0xc3d2e1f0;}/*********************************the end of the function*//*********************************the function used to compute the 80 loops and save the result into the global var state[]*/void shaTran(unsigned char * buf,unsigned int * state){ int i,j; unsigned int A,B,C,D,E,temp; /*the Register "A,B,C,D,E" and temp*/ unsigned int K[4]; /*the K[t] used in SHA-1*/ unsigned int W[80]; /*the W[t] used in SHA-1*/ unsigned char * p = (unsigned char *)W; /*the (unsigned char *)p point to W[0]*/ /*********************************init the Register "A,B,C,D,E"*/ A = state[0]; B = state[1]; C = state[2]; D = state[3]; E = state[4]; /*********************************init K*/ K[0] = 0x5a827999; K[1] = 0x6ed9eba1; K[2] = 0x8f1bbcdc; K[3] = 0xca62c1d6; /*********************************compute W[t]*/ /*compute W[t] 0<=t<=15*/ /*++++++++++++++++++++++++++++++++ Notice that The IA32 System use little-endian to save data in Main Memory So change the sequence before use it ++++++++++++++++++++++++++++++++*/ for(i=0;i<16;i++) { j = 4*i; p[j+3] = buf[j]; p[j+2] = buf[j+1]; p[j+1] = buf[j+2]; p[j] = buf[j+3]; } /*compute W[t] 16<=t<=79*/ for(i=16;i<80;i++) { W[i] = ((W[i-16]^W[i-14]^W[i-8]^W[i-3])<<1) | ((W[i-16]^W[i-14]^W[i-8]^W[i-3])>>31); } /*********************************compute 1st loop*/ for(i=0;i<20;i++) { temp = E + f1(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[0]; E = D; D = C; C = (B<<30)|(B>>2); B = A; A = temp; } /*********************************compute 2nd loop*/ for(i=20;i<40;i++) { temp = E + f2(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[1]; E = D; D = C; C = (B<<30)|(B>>2); B = A; A = temp; } /*********************************compute 3rd loop*/ for(i=40;i<60;i++) { temp = E + f3(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[2]; E = D; D = C; C = (B<<30)|(B>>2); B = A; A = temp; } /*********************************compute 4th loop*/ for(i=60;i<80;i++) { temp = E + f4(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[3]; E = D; D = C; C = (B<<30)|(B>>2); B = A; A = temp; } /*********************************add the vars back into the global var state[]*/ state[0] += A; state[1] += B; state[2] += C; state[3] += D; state[4] += E;}/*********************************the end of the function*//*********************************the function used to padding*/void sha(unsigned char *buf, int len, unsigned int * state, unsigned int f1,unsigned int f2){ int i; unsigned int floop1,floop2; /*use floop1:floop2 to represent the length of the file in bit*/ unsigned char flen[8]; /*use unsigned char flen[8] to transform the floop1:floop2 in last block*/ unsigned char *p1 = (unsigned char *)&floop1; unsigned char *p2 = (unsigned char *)&floop2; floop1 = f1; floop2 = f2; floop2 = floop2 + (unsigned int)(len*8); /*add the last block's length(in bit)*/ /*********************************compute the whole file's length*/ /*compute the length of the file and save it into unsigned char flen[8]*/ /*++++++++++++++++++++++++++++++++ Notice that The IA32 System use little-endian to save data in Main Memory So change the sequence before use it ++++++++++++++++++++++++++++++++*/ /*printf("floop1 = %08x\n",floop1); printf("floop2 = %08x\n",floop2);*/ for(i=0; i<4; i++) { flen[3-i] = *p1; flen[7-i] = *p2; p1++; p2++; } /*********************************do the padding*/ /*the file's length(bit) < 448 */ if(len<56) { /*pad it like 1000000...(bit) from the end(buf[len-1]) to the buf[55]*/ buf[len] = 0x80; for(i=len+1; i<56; i++) { buf[i] = 0x00; } /*pad the last 64bit using flen[8](the length of the file computed before)*/ for(i=56; i<64; i++) { buf[i] = flen[i-56]; } /*then call the function "shaTran" to do the loop*/ shaTran(buf,state); } /*the file's length(bit) >= 448 */ else { /*pad the 1st block with a number of bit 100000... until the end of the buf(buf[63])*/ buf[len] = 0x80; for(i=len+1; i<64; i++) { buf[i] = 0x00; } /*call the function "shaTran" to do the loop*/ shaTran(buf,state); /*pad the 1st block with a number of bit 000000... until the 448 bit(buf[55])*/ for(i=0; i<56; i++) buf[i] = 0x00; /*pad the last 64bit using flen[8](the length of the file computed before)*/ for(i=56; i<64; i++) { buf[i] = flen[i-56]; } /*call the function "shaTran" to do the loop*/ shaTran(buf,state); }}/*********************************the end of the function*/int shaDriver(const char * pw, char * result){ unsigned char buf[64]; /*the input block of SHA-1*/ /*char pw[17] = "YamaP";*/ char str1[9], str2[9], str3[9], str4[9], str5[9]; /*the 5 output substrings*/ /*char result[41]; the string result after hashing*/ FILE * file_w, * file_r; /*file streams for writing and reading*/ int len; /*used to save the length of one read from the file (byte)*/ unsigned int floop1,floop2; /*use floop1:floop2 to represent the length of the file in bit*/ floop1 = floop2 = 0; /*at 1st make them equal 0*/ /*********************************Init the global var*/ Init(); if (!(file_w = fopen("pw.tmp", "w"))) { printf("can not open file!!!\n"); return -1; } fputs(pw, file_w); fclose(file_w); /*********************************can not open file error*/ if (!(file_r = fopen("pw.tmp", "rb"))) { printf("can not open file!!!\n"); return -1; } /*********************************read data from the file*/ while(!feof(file_r)) { /*********************************each time read 64 bits into buf at most*/ len=fread(buf,1,64,file_r);/*len used to save the length of each read*/ /*********************************read file error*/ if(ferror(file_r)) { printf("read file error!!!\n"); return -1; } /*********************************the buf[64] is full*/ if(len == 64) { /*use 2 unsigned int to represent 1 64bit number, floop1:floop2*/ if((floop1 == 0xffffffff) && (floop2 == 0xfffffe00)) { printf("file larger than 2exp(64)"); return -1; } if(floop2 != 0xfffffe00)floop2+=512; else { floop1++; floop2 = 0; } /*call the function "shaTran" to do the loop*/ shaTran(buf,state); } /*********************************less than 512 bits need to pad*/ else { /*call the function "sha" to do the padding and other compute*/ sha(buf,len,state,floop1,floop2); } } /*********************************print the digest*/ sprintf(str1, "%08x", state[0]); sprintf(str2, "%08x", state[1]); sprintf(str3, "%08x", state[2]); sprintf(str4, "%08x", state[3]); sprintf(str5, "%08x", state[4]); strcpy(result, str1); strcat(result, str2); strcat(result, str3); strcat(result, str4); strcat(result, str5); remove("pw.tmp"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -