📄 sha.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 + -