⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha-1.cpp

📁 MAC算法SHA—1算法的C语言实现源码
💻 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 + -