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

📄 s-des.cpp

📁 在控制台下用simple DES实现对任意文件的加解密
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//将一个字符转化成二进制表示
void ToBinary(char ch,int *binary)
{
	char temp=ch;

	//字符的表示范围是-128到127
	//不能和128相与,必需先右移再相与
	ch=ch>>7;
	ch=ch&1;
	binary[0]=ch;

	ch=temp;
	ch=ch&64;
	ch=ch>>6;
	binary[1]=ch;

	ch=temp;
	ch=ch&32;
	ch=ch>>5;
	binary[2]=ch;

	ch=temp;
	ch=ch&16;
	ch=ch>>4;
	binary[3]=ch;

	ch=temp;
	ch=ch&8;
	ch=ch>>3;
	binary[4]=ch;

	ch=temp;
	ch=ch&4;
	ch=ch>>2;
	binary[5]=ch;

	ch=temp;
	ch=ch&2;
	ch=ch>>1;
	binary[6]=ch;

	ch=temp;
	ch=ch&1;
	binary[7]=ch;
}

//将二进制结果转化成字符
void ToChar(int *binary,char *out_char)
{
	int sum=0;
	//字符只接收-128到127之间的数值,所以要考虑符号位
	sum=binary[0]*(-1)*128+binary[1]*64+binary[2]*32+binary[3]*16+binary[4]*8+binary[5]*4+binary[6]*2+binary[7]*1;
	*out_char=(char)sum;
}


int P10[]={2,4,1,6,3,9,0,8,7,5};


//初始置换P10
void Key_IP10(int *in,int *out)
{
	for(int i=0;i<10;i++)
		out[i]=in[P10[i]];
}

//循环左移一位
void L_Shift1(int *in,int *out)
{
	for(int i=0;i<4;i++)
		out[i]=in[i+1];
	out[4]=in[0];
	for(int i=5;i<9;i++)
		out[i]=in[i+1];
	out[9]=in[5];		
}

//循环左移两位
void L_Shift2(int *in,int *out)
{
	for(int i=0;i<3;i++)
		out[i]=in[i+2];
	out[3]=in[0];
	out[4]=in[1];
	for(int i=5;i<8;i++)
		out[i]=in[i+2];
	out[8]=in[5];	
	out[9]=in[6];
}

int P8[]={5,2,6,3,7,4,9,8};

//P8置换生成子密钥K1
void Key_P8(int *P10_Key,int *P8_Key)
{
	for(int i=0;i<8;i++)
		P8_Key[i]=P10_Key[P8[i]];
}

int Extend[]={3,0,1,2,1,2,3,0};

int PTP8[]={1,5,2,0,3,7,4,6};

void PlainText_P8(int *PlainText)
{
	int temp[8];
	for(int i=0;i<8;i++)
		temp[i]=PlainText[PTP8[i]];
	for(int i=0;i<8;i++)
		PlainText[i]=temp[i];
}

//扩展右半部分
void ExtendRight(int *right, int *etRight)
{
	for(int i=0;i<8;i++)
		etRight[i]=right[Extend[i]];
}

//扩展的右半部分与子密钥K1异或
void EtR_xor_K(int *EtRight,int *key,int *EtR_xor_Key)
{
	for(int i=0;i<8;i++)
		EtR_xor_Key[i]=EtRight[i]^key[i];
}

int S0[4][4]={{1,0,3,2},{3,2,1,0},{0,2,1,3},{3,1,3,2}};
int S1[4][4]={{0,1,2,3},{2,0,1,3},{3,0,1,0},{2,1,0,3}};

//扩展的右半部分与子密钥K1异或并且经过S0S1盒
void S0S1_Substitute(int *EtR_xor_Key,int *S0S1_Sub)
{
	int row1,row2,column1,column2;
	int num1,num2;
	int temp1[2],temp2[2];
	row1=EtR_xor_Key[0]*2+EtR_xor_Key[3];
	column1=EtR_xor_Key[1]*2+EtR_xor_Key[2];
	row2=EtR_xor_Key[4]*2+EtR_xor_Key[7];
	column2=EtR_xor_Key[5]*2+EtR_xor_Key[6];

	num1=S0[row1][column1];
	num2=S1[row2][column2];

	for(int i=0;i<2;i++)
	{
		temp1[i]=num1%2;
		num1=num1/2;
	}
	for(int i=0;i<2;i++)
	{
		temp2[i]=num2%2;
		num2=num2/2;
	}

	for(int i=0;i<2;i++)
		S0S1_Sub[i]=temp1[1-i];
	for(int i=2;i<4;i++)
		S0S1_Sub[i]=temp2[3-i];
}

int P4[4]={1,3,2,0};

//S0S1输出的4位进行P4置换
void S0S1_out_P4(int *S0S1_Sub,int *S0S1_Sub_P4)
{
	for(int i=0;i<4;i++)
		S0S1_Sub_P4[i]=S0S1_Sub[P4[i]];
}

//明文左半部分与操作后的右半部分异或
void PTL_xor_chPTR(int *PT_L,int *S0S1_Sub_P4,int *L_xor_chR)
{
	for(int i=0;i<4;i++)
		L_xor_chR[i]=PT_L[i]^S0S1_Sub_P4[i];
}

//交换左右两部分
void Switch(int *PT_L,int *PT_R)
{
	int temp[4];
	for(int i=0;i<4;i++)
		temp[i]=PT_L[i];
	for(int i=0;i<4;i++)
		PT_L[i]=PT_R[i];
	for(int i=0;i<4;i++)
		PT_R[i]=temp[i];
}

int P8ni[]={3,0,2,4,6,1,7,5};

void P8_ni(int *in,int *out)
{
	for(int i=0;i<8;i++)
		out[i]=in[P8ni[i]];
}

/***********************************
加解密操作
***********************************/
void encrypt(char in,int *int_key,char *out,int flag)
{	
	//将明文转化成二进制
	int binary[8];	
	ToBinary(in,binary);

	//明文P8置换
	PlainText_P8(binary);

	//明文左右部分分别为PT_L[4],PT_L[4]
	int PT_L[4];
	for(int i=0;i<4;i++)
		PT_L[i]=binary[i];
		
	int PT_R[4];
	for(int i=0;i<4;i++)
		PT_R[i]=binary[i+4];		

	//P10初始置换的密钥
	int P10_Key[10];	
	Key_IP10(int_key,P10_Key);

	//一次循环左移密钥
	int Key_LShift1[10];	
	L_Shift1(P10_Key,Key_LShift1);	

	//两次循环左移密钥
	int Key_LShift2[10];	
	L_Shift2(Key_LShift1,Key_LShift2);	
	
	//产生子密钥K1		
	int P8_Key_K1[8];	
	Key_P8(Key_LShift1,P8_Key_K1);
	
	//产生子密钥K2		
	int P8_Key_K2[8];	
	Key_P8(Key_LShift2,P8_Key_K2);

	//明文右半部分扩展
	int Extend_PT_R[8];	
	ExtendRight(PT_R,Extend_PT_R);

	//扩展后与子密钥K1异或
	int EtR_xor_Key[8];		
	if(flag==1)
		EtR_xor_K(Extend_PT_R,P8_Key_K1,EtR_xor_Key);
	else if(flag==0)
		EtR_xor_K(Extend_PT_R,P8_Key_K2,EtR_xor_Key);

	//经过S0S1盒
	int S0S1_Sub[4];	
	S0S1_Substitute(EtR_xor_Key,S0S1_Sub);

	//经过S盒后进行置换
	int S0S1_Sub_P4[4];	
	S0S1_out_P4(S0S1_Sub,S0S1_Sub_P4);

	//左半部分与经过改变的右半部分异或
	int L_xor_chR[4];	
	PTL_xor_chPTR(PT_L,S0S1_Sub_P4,L_xor_chR);

	Switch(L_xor_chR,PT_R);
	int new_PTL[4],new_PTR[4];	//交换后字符串新的左右部分

	for(int i=0;i<4;i++)
		new_PTL[i]=L_xor_chR[i];
	for(int i=0;i<4;i++)
		new_PTR[i]=PT_R[i];

	int new_Extend_PT_R[8];	//新的明文右半部分扩展
	ExtendRight(new_PTR,new_Extend_PT_R);

	int new_EtR_xor_Key[8];		//扩展后与子密钥K2异或
	if(flag==1)
		EtR_xor_K(new_Extend_PT_R,P8_Key_K2,new_EtR_xor_Key);
	else if(flag==0)
		EtR_xor_K(new_Extend_PT_R,P8_Key_K1,new_EtR_xor_Key);
	
	int new_S0S1_Sub[4];	//经过S0S1盒
	S0S1_Substitute(new_EtR_xor_Key,new_S0S1_Sub);

	int new_S0S1_Sub_P4[4];	//经过S盒后进行置换
	S0S1_out_P4(new_S0S1_Sub,new_S0S1_Sub_P4);

	int new_L_xor_chR[4];	//左半部分与经过改变的右半部分异或
	PTL_xor_chPTR(new_PTL,new_S0S1_Sub_P4,new_L_xor_chR);
	
	int cipherText_former[8],cipherText[8];
	for(int i=0;i<8;i++)
	{
		if(i<4)
			cipherText_former[i]=new_L_xor_chR[i];
		else if(i>=4)
			cipherText_former[i]=new_PTR[i-4];
	}

	P8_ni(cipherText_former,cipherText);

	ToChar(cipherText,out);
	//printf("\n");
}


int *enKey;
//传递用户输入的密钥给加解密函数
void set_Key(int *key)
{
	enKey=key;
}
void encrypt_File(char *inPath,char *outPath,int flag)
{
	FILE *fpInText,*fpOutText;

	//打开一个二进制文件
	fpInText=fopen(inPath,"rb");
	if(fpInText==NULL) 
		{ 
			printf("\n不能打开该文件,可能你还未创建"); 
			exit(0); 
		}
	//创建一个文本文件
	fpOutText=fopen(outPath,"wb");
	if(fpOutText==NULL)
		{ 
			printf("创建outputfile.txt失败!"); 
			exit(0); 
		}

	int flag2;
	flag2=flag;

	char in,ch;
	in=fgetc(fpInText);
	
	while(!feof(fpInText))
	{
		ch=in;
		in=fgetc(fpInText);

		char out_char;
		char *point_out;
		point_out=&out_char;

		//对文件的每个字符进行加密
		encrypt(ch,enKey,point_out,flag2);
		//并将加密结果输入到加密文件中
		fputc(out_char,fpOutText);
	}

	fclose(fpInText);
	fclose(fpOutText);
}


int main(int argc,char *argv[])
{
	char ch_key[80];
	char a[]="da",b[]="-e",c[]="-d";
	int int_key[10];
	char ch_key_first,ch_key_second;
	//int choice;

	if(argc!=5)
	{
		printf("\n请用命令行形式执行!\n");
		exit(0);
	}
		
	int flag;
	if((strcmp(argv[1],b))==0)
		flag=1;
	else if((strcmp(argv[1],c))==0)
		flag=0;

	//将控制台第二个字符串赋值给密码
	strcpy(ch_key,argv[2]);
	
	//将前两个字母取出,且16bit中只有前面10bit才有效,赋值给key
	ch_key_first=ch_key[0];
	int binary1[8];		//用于接收第一个密钥字符的8bit
	ToBinary(ch_key_first,binary1);
	ch_key_second=ch_key[1];
	int binary2[8];		//用于接收第二个密钥字符的8bit
	ToBinary(ch_key_second,binary2);

	for(int i=0;i<8;i++)
		int_key[i]=binary1[i];

	int_key[8]=binary2[0];
	int_key[9]=binary2[1];

	set_Key(int_key);
	encrypt_File(argv[3],argv[4],flag);
	if(flag==1)
		printf("加密成功!\n");
	else if(flag==0)
		printf("解密成功!\n");

	//printf("\n");
	return 0;
}
	





⌨️ 快捷键说明

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