📄 sha-1.cpp
字号:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define P1(B,C,D) (B&C)|(~B&D)
#define P2(B,C,D) B^C^D
#define P3(B,C,D) (B&C)|(B&D)|(C&D)
#define P4(B,C,D) B^C^D
FILE *in,*out;
unsigned int A=0x67452301;
unsigned int B=0xEFCDAB89;
unsigned int C=0x98BADCFE;
unsigned int D=0x10325476;
unsigned int E=0xC3D2E1F0;
unsigned int K[4] = {0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};
int AddData(__int64 ); //填充最后一块数据,并处理填充后的数据
int AddLength(__int64 ,unsigned char *); //添加数据长度
unsigned int S(unsigned int ,int ); //移位
int ProcessData(unsigned char * ); //处理数据块
unsigned int* ExpandData(unsigned char *); //扩充数据
int main()
{
unsigned char *plain=(unsigned char *)malloc(64*sizeof(unsigned char));
unsigned int *hash=(unsigned int *)malloc(5*sizeof(unsigned int));
__int64 length=0;
__int64 datablock=0;
if( (in = fopen("1.txt","rb")) == NULL) //打开文件
{
printf("Can't open file!");
exit(0);
}
if( (out = fopen("2.txt","wb")) == NULL) //打开文件
{
printf("Can't open file!");
exit(0);
}
fseek(in,0,2); //使文件指针指到文件中最后一个字符
length=ftell(in); //得到文件长度存在length里
fseek(in,0,0); //使文件指针指到文件中第一个字符
datablock = length / 64;
for(__int64 i=0;i<datablock;i++) //读出数据块长度为512bit的数据块
{
fread(&plain,64,1,in);
ProcessData(plain); //处理数据块
}
AddData(length); //填充最后一块数据,并处理填充后的数据
fprintf(out,"%u%u%u%u%u",A,B,C,D,E); //将公私钥写入文件
fclose(in);
fclose(out);
return 0;
}
int ProcessData(unsigned char *plain) //处理数据块
{
unsigned int AA=A;
unsigned int BB=B;
unsigned int CC=C;
unsigned int DD=D;
unsigned int EE=E;
unsigned int a=A;
unsigned int b=B;
unsigned int c=C;
unsigned int d=D;
unsigned int e=E;
unsigned int *W=(unsigned int *)malloc(80*sizeof(unsigned int));
W=ExpandData(plain); //扩充数据
for(int i=0;i<20;i++) //第一轮
{
AA=((unsigned __int64)a + P1(b,c,d) + S(a,5) + W[i] + K[0]) % 0x100000000;
BB=a;
CC=S(b,30);
DD=c;
EE=d;
a=AA;
b=BB;
c=CC;
d=DD;
e=EE;
}
for(int i=20;i<40;i++) //第二轮
{
AA=((unsigned __int64)a + P2(b,c,d) + S(a,5) + W[i] + K[1]) % 0x100000000;
BB=a;
CC=S(b,30);
DD=c;
EE=d;
a=AA;
b=BB;
c=CC;
d=DD;
e=EE;
}
for(int i=40;i<60;i++) //第三轮
{
AA=((unsigned __int64)a + P3(b,c,d) + S(a,5) + W[i] + K[2]) % 0x100000000;
BB=a;
CC=S(b,30);
DD=c;
EE=d;
a=AA;
b=BB;
c=CC;
d=DD;
e=EE;
}
for(int i=60;i<80;i++) //第四轮
{
AA=((unsigned __int64)a + P4(b,c,d) + S(a,5) + W[i] + K[3]) % 0x100000000;
BB=a;
CC=S(b,30);
DD=c;
EE=d;
}
A=(AA+A) % 0x100000000; //模加运算
B=(BB+B) % 0x100000000;
C=(CC+C) % 0x100000000;
D=(DD+D) % 0x100000000;
E=(EE+E) % 0x100000000;
return 0;
}
unsigned int* ExpandData(unsigned char *plain) //扩充数据
{
unsigned int *W=(unsigned int *)malloc(80*sizeof(unsigned int));
W=(unsigned int*)plain;
for(int i=16;i<80;i++) //将16个字的明文扩充为80字的,并存在W数组里
W[i]=(W[i-16]^W[i-14]^W[i-8]^W[i-3]) >> 1;
return W;
}
int AddData(__int64 length) //填充最后一块数据,并处理填充后的数据
{
unsigned char *plain=(unsigned char *)malloc(64*sizeof(unsigned char));
int k=0;
for(k;k<length % 64;k++) //先读出最后一个数据块的数据
plain[k]=getc(in);
if(length % 64 < 448) //如果最后一个数据块长度小于448bit(包括0bit),在其后补数,再补上64bit的数据长度
{
plain[k]=0x80;
for(k++;k<56;k++)
plain[k]=0x00;
AddLength(length,plain); //添加数据长度
ProcessData(plain); //处理数据块
}
else if(length % 64 > 448) //如果最后一个数据块长度大于448bit,在其后再补一个数据块,再补上64bit的数据长度
{
plain[k]=0x80;
for(k++;k<64;k++)
plain[k]=0x00;
ProcessData(plain); //处理数据块
for(int j=0;j<56;j++)
plain[j]=0x00;
AddLength(length,plain); //添加数据长度
ProcessData(plain); //处理数据块
}
return 0;
}
int AddLength(__int64 length,unsigned char *plain) //添加数据长度
{
plain[56]=(length & 0xFF00000000000000) >> 56;
plain[57]=(length & 0x00FF000000000000) >> 48;
plain[58]=(length & 0x0000FF0000000000) >> 40;
plain[59]=(length & 0x000000FF00000000) >> 32;
plain[60]=(length & 0x00000000FF000000) >> 24;
plain[61]=(length & 0x0000000000FF0000) >> 16;
plain[62]=(length & 0x000000000000FF00) >> 8;
plain[63]=(length & 0x00000000000000FF);
return 0;
}
unsigned int S(unsigned int G,int k) //移位
{
G=G>>k;
return G;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -