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

📄 sha.h

📁 用SHA算法实现对任意文件的hash摘要
💻 H
字号:
#include<stdlib.h>
#include<math.h>

#define ROUND 20
#define BLOCKSIZE 16
#define ROUNDNUM  80

/*
*预定义常用的内置数据类型
*/
typedef unsigned __int64 UINT64;
typedef unsigned int UINT32;
typedef unsigned char UCHAR;

/*
*定义本程序所使用的全局变量
*/
UINT32 K[4] = {
				0X5A827999,
				0X6ED9EBA1,
				0X8F1BBCDC,
				0XCA62C1D6
				};//定义常量字
UINT32 H[5] = {
				0X67452301,
				0XEFCDAB89,
				0X98BADCFE,
				0X10325476,
				0XC3D2E1F0
				};//定义五字缓冲区
UINT32 W[80] = {0};//定义80字缓冲区
UINT32 temp[BLOCKSIZE] = {0};//明文缓存区

/*
函数:	基本逻辑函数
功能:	执行位逻辑运算
参数:	输入三个UINT32变量,返回一个UINT32变量
注意:	轮数不同,采用的逻辑函数也不同
*/
UINT32 Ft(UINT32 t,UINT32 B,UINT32 C,UINT32 D)
{
	UINT32 arrange = t/20;
	switch(arrange)
	{
		case 0:
			return (B&C)|((~B)&D);
		case 1:
		case 3:
			return (B^C^D);
		case 2:
			return (B&C)|(B&D)|(C&D);
	};
}

/*
函数:	循环移位函数
功能:	对待处理数据左移n位并返回移位后的数据
参数:	移位位数,需要移位的数据
注意:	nothing
*/

UINT32 Shift(UINT32 n,UINT32 sftNum)
{
	return (sftNum<<n)|(sftNum>>(32-n));
}

/*
函数:	Wt
功能:	512bits-->32bits*80
参数:	指向明文数组的指针
注意:	nothing
*/

void Wt(UINT32 plainText[])
{
	UINT32 temp = 0,t = 0;
	int i;
	for(i = 0; i<BLOCKSIZE; i++)
		W[i] = plainText[i];
	for(i = 16; i<ROUNDNUM; i++)
	{
		temp = W[i-3]^W[i-8]^W[i-14]^W[i-16];
		W[i] = Shift(1,(temp));
	}
}

/*
函数:	明文单步处理函数
功能:	每次调用该函数,处理一个512bit明文
参数:	指向明文数组的指针
注意:	nothing
*/
void PlainDispose(UINT32 text[])
{
	UINT32 temp = 0,i = 0,j = 0;
	UINT32 A,B,C,D,E;
	A = H[0];B = H[1];C = H[2];D = H[3];D = H[4];

	Wt(text);//初始化W数组
	UINT32 k;
	for( k = 0; k<ROUNDNUM; k++)//80轮处理过程
	{
		i = k/20;//i用来作为四轮处理的下标
		temp = (Shift(5,A) + Ft(k,B,C,D) + E + W[k] + K[i]);
		E = D;D = C;C = Shift(30,B);B = A;A = temp;
	}
	H[0] += A;
	H[1] += B; 
	H[2] += C; 
	H[3] += D; 
	H[4] += E;
}

/*
函数:	文件预处理函数,主要就是填充
功能:	每次调用该函数,处理一个512bit明文
参数:	控制台传来的infile和outfile,返回文件长度
注意:	nothing
*/

 UINT64 filedispose(char *argv[])
 {
	FILE*fptemp,*fp;
	UINT64 foradd=0,num512=0,i=0;

	UINT32 aaaa = 0;

	int m=0;
	UCHAR ch,filelen[8]={0};
	if((fp=fopen(argv[1],"r"))==NULL)
	{
		printf("打开待摘要的文件失败,请检查\n");
	    exit(0);
	}
    if((fptemp=fopen(argv[2],"wb+"))==NULL)
	{
		printf("打开存储摘要信息的文件失败,请检查\n");
		exit(0);
	}   
	/**/
	while(fread(&ch,sizeof(char),1,fp) != 0)
	{
		putc(ch,fptemp);	
		i++;
	}//遍历文件内容,数出文件字符个数,并写入另一个临时文件
	//i=ftell(fptemp); 
	num512=((i*8)/512)+1;//该文件所含有的512字节的数目,即使是完全的512整数块,还是要加1,因为还是要新添加一整块
    foradd=512-(i*8-448)%512;//计算出将要被填充的bit位数,即使已经是512的整数倍,再添加448bits
	fseek(fptemp,0,SEEK_END);//让文件指针指向文件末尾
	fputc(0x80,fptemp);//第一个填充字符为10000000
	int j;
	for(j=1;j<foradd/8;j++)
		fputc(0x00,fptemp);//填充其余字符

	filelen[7] = i & 0xff00000000000000;
	filelen[6] = i & 0x00ff000000000000;
	filelen[5] = i & 0x0000ff0000000000;
	filelen[4] = i & 0x000000ff00000000;
	filelen[3] = i & 0x00000000ff000000;
	filelen[2] = i & 0x0000000000ff0000;
	filelen[1] = i & 0x000000000000ff00;
	filelen[0] = i & 0x00000000000000ff;

	for(m=7;m>=0;m--)
		putc(filelen[m],fptemp);//将文件长度写入文件末尾,用64字节保存,最低有效位在前
	  //fwrite(&i,sizeof(UINT64),1,fptemp);
	fclose(fptemp);
	return i;  //返回文件字节数
 }

/*
函数:	输出生成摘要的函数
功能:	将摘要写入文件,打印屏幕
参数:	控制台传来的infile和outfile,存放摘要值的数组
注意:	nothing
*/
 
void OutPut(char*argv[],UINT32 H[])
{
	FILE*fp;
    if((fp=fopen(argv[2],"wb+"))==NULL)
    {
		printf("打开临时文件失败,请检查\n");
	    exit(0);
    }
	printf("信息摘要生成,已经保存到文件%s:\n",argv[2]);
	for(int j=0;j<5;j++)//输出最终摘要信息
	{
		printf("%x",H[j]);
		fwrite(&H[j],sizeof(UINT32),1,fp);
	}
	printf("\n");
	fclose(fp);//关闭文件
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -