📄 s-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 + -