📄 main.c
字号:
/**使用des算法加密图片、解密图片、对位进行操作
*/
#include <stdio.h>
#include <stdlib.h>
#define BUFFSIZE 140
#define LUN 16//轮数
const char S[8][4*16] =
{// S盒子
// S1
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
// S2
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
// S3
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
// S4
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
3, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
// S5
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13,
0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3,
9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6,
3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10,
4, 5, 3},
// S6
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14,
7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0,
11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1,
13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6,
0, 8, 13},
// S7
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5,
10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2,
15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0,
5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14,
2, 3, 12},
// S8
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5,
0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0,
14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15,
3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3,
5, 6, 11}
};
const char P[] =
{// P-盒置换
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
const char IP[]=
{//明文初始置换表
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
const char nIP[] =
{// 逆初始置换
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
const char E[] =
{// 右明文扩展置换
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
const char KPC_1[] =
{// 密钥置换
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
const char KPC_2[48]=
{// 压缩置换
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
const char SLR[16] =
{// 每轮移动的位数
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
char KEY[LUN][6];//存放16个生成子密钥
void cycle28(char mingwenx[4],int i)
{//i为移位位数 密钥28左移
char a,b,c,d;
a=mingwenx[0]>>(4-i);
b=mingwenx[1]>>(8-i);
c=mingwenx[2]>>(8-i);
d=mingwenx[3]>>(8-i);
if (i==1)
{
a=a&0x01;
b=b&0x01;
c=c&0x01;
d=d&0x01;
}
else
{
a=a&0x03;
b=b&0x03;
c=c&0x03;
d=d&0x03;
}
mingwenx[0]=mingwenx[0]<<i;
mingwenx[1]=mingwenx[1]<<i;
mingwenx[2]=mingwenx[2]<<i;
mingwenx[3]=mingwenx[3]<<i;
mingwenx[0]=mingwenx[0]|b;
mingwenx[1]=mingwenx[1]|c;
mingwenx[2]=mingwenx[2]|d;
mingwenx[3]=mingwenx[3]|a;
}
void miyueyasuozhihuan(char miyue1[],char miyue2[],const char zhihuanbiao[],int num,int L)
{//28位密钥压缩置换
int A,B;
int i;
char mid[8];
for (i=0;i<num;i++)
{
if (zhihuanbiao[i]<=28)
{
A=(zhihuanbiao[i]+3)/8;
B=(zhihuanbiao[i]+3)%8;
mid[i%8]=((miyue1[A]>>(7-B))&0x01)<<(7-i%8);
}
else
{
A=(zhihuanbiao[i]-25)/8;
B=(zhihuanbiao[i]-25)%8;
mid[i%8]=((miyue2[A]>>(7-B))&0x01)<<(7-i%8);
}
if (i==7||i==15||i==23||i==31||i==39||i==47)
KEY[L-1][i/8]=mid[0]|mid[1]|mid[2]|mid[3]|mid[4]|mid[5]|mid[6]|mid[7];
}
}
void mingwenzhihuan(char sour1[],char dest1[],const char zhihuanbiao1[],int num)
{//明文初始置换,明文扩展置换,P置换,num为置换的位数即dest[]位数
int i,A,B;
char mid[8];
for (i=0;i<num;i++)
{
A=(zhihuanbiao1[i]-1)/8;
B=(zhihuanbiao1[i]-1)%8;
mid[i%8]=((sour1[A]>>(7-B))&0x01)<<(7-i%8);
if (!((i+1)%8))
dest1[i/8]=mid[0]|mid[1]|mid[2]|mid[3]|mid[4]|mid[5]|mid[6]|mid[7];
}
}
void Shetihuan(char sour2[],char dest2[])
{
int i;
char mid,hang,lie;
char mhang[2];
char mlie[4];
char shuchu[8]={'\0'};
for (i=0;i<48;i++)
{
mid=(sour2[i/8]>>(7-i%8))&0x01;
if ((i%6)==0||(i%6)==5)
{
if (i%6==0)
mhang[0]=mid;
else
mhang[1]=mid;
}
else
mlie[(i%6)-1]=mid;
if (!((i+1)%6))
{
hang=((mhang[0]<<1)|mhang[1])&0x03;
lie=((mlie[0]<<3)|(mlie[1]<<2)|(mlie[2]<<1)|mlie[3])&0x0f;
shuchu[i/6]=S[i/6][(int)hang*16+(int)lie];
}
}
dest2[0]=(shuchu[0]<<4)|(shuchu[1]&0x0f);
dest2[1]=(shuchu[2]<<4)|(shuchu[3]&0x0f);
dest2[2]=(shuchu[4]<<4)|(shuchu[5]&0x0f);
dest2[3]=(shuchu[6]<<4)|(shuchu[7]&0x0f);
}
void miyuechansheng(char miyue[])
{///64位给定密钥-》56密钥-》16*48位子密钥
char yasuojieguo[7];
char miyue1[4];
char miyue2[4];
char midd[4];
int x;
mingwenzhihuan(miyue,yasuojieguo,KPC_1,56);///密钥初置换64->56
miyue2[3]=yasuojieguo[6];
miyue2[2]=yasuojieguo[5];
miyue2[1]=yasuojieguo[4];
miyue2[0]=yasuojieguo[3]&0x0f;
midd[0]=(yasuojieguo[0]>>4)&0x0f;
midd[1]=(yasuojieguo[1]>>4)&0x0f;
midd[2]=(yasuojieguo[2]>>4)&0x0f;
midd[3]=(yasuojieguo[3]>>4)&0x0f;
miyue1[0]=midd[0]&0x0f;
miyue1[1]=(yasuojieguo[0]<<4)|midd[1];
miyue1[2]=(yasuojieguo[1]<<4)|midd[2];
miyue1[3]=(yasuojieguo[2]<<4)|midd[3];///分为两个28位密钥
for (x=0;x<16;x++)
{
cycle28(miyue1,SLR[x]);
cycle28(miyue2,SLR[x]);///循环移位
miyueyasuozhihuan(miyue1,miyue2,KPC_2,48,x+1);///产生密钥存入KEY
}
}
void des(char mingwen2[],int flag)
{//加密明文,flag为1表示加密,0表示解密。加密后结果也存入mingwen[]
//char *LPT,*RPT,*M;
char LPT[4],RPT[4],M[4];
char middle[8];
char dest[6];
char midd1[4];
//char KEYY[6]={0x30,0xec,0x88,0x32,0x33,0x71};
int i,x,h,hh,t;
mingwenzhihuan(mingwen2,middle,IP,64);//明文初置换
for (i=0;i<4;i++)
{
LPT[i]=middle[i];
RPT[i]=middle[i+4];
}
for (x=0;x<16;x++)
{
for (t=0;t<4;t++)
M[t]=RPT[t];
mingwenzhihuan(RPT,dest,E,48);//右明文扩展至换
if (flag==1)
for (h=0;h<6;h++)
{
dest[h]=dest[h]^KEY[x][h];
}
else
for (h=0;h<6;h++)
{
dest[h]=dest[h]^KEY[15-x][h];
}
Shetihuan(dest,midd1);//S置换
mingwenzhihuan(midd1,RPT,P,32);//P置换
for (hh=0;hh<4;hh++)
{
LPT[hh]=RPT[hh]^LPT[hh];
}
for (t=0;t<4;t++)
RPT[t]=LPT[t];
for (t=0;t<4;t++)
LPT[t]=M[t];
}
for (i=0;i<4;i++)
{
middle[i]=RPT[i];
middle[i+4]=LPT[i];
}
mingwenzhihuan(middle,mingwen2,nIP,64);
}
int main()
{
FILE *fp1,*fp2;
int num,num2,i,n,x;
char buff[BUFFSIZE];
char buff2[8];
char buff3[8]={0,0,0,0,0,0,0,0};
char buff4[8];
// char IV[8];
char myname[9];
printf("输入1加密,输入0解密: ");
scanf("%d",&num);
printf("输入1使用ECB,输入0使用CBC: ");
scanf("%d",&num2);
printf("Please enter the KEY: ");
getchar();
gets(myname);
miyuechansheng(myname);
if (num==1)
{
fp1=fopen("read.bmp","rb");
fp2=fopen("write1.bmp","wb");
fread(buff,sizeof(char),BUFFSIZE,fp1);
fwrite(buff,BUFFSIZE,1,fp2);
}
else if (num==0)
{
fp1=fopen("write1.bmp","rb");
fp2=fopen("write2.bmp","wb");
fread(buff,sizeof(char),BUFFSIZE,fp1);
fwrite(buff,BUFFSIZE,1,fp2);
}
if (num2==1)///EBC
{
while ((n=fread(buff2,sizeof(char),8,fp1))==8)
{
des(buff2,num);
fwrite(buff2,8,1,fp2);
}
if (n!=0)
{
for (i=0;i<8-n;i++)
{
buff2[8-i]=0;
}
des(buff2,num);
fwrite(buff2,8,1,fp2);
}
}
if (num2==0)///CBC
{
if (num==1)
{
while ((n=fread(buff2,sizeof(char),8,fp1))==8)
{
for (x=0;x<8;x++)
buff2[x]=buff2[x]^buff3[x];
des(buff2,num);
for (x=0;x<8;x++)
buff3[x]=buff2[x];
fwrite(buff2,8,1,fp2);
}
if (n!=0)
{
for (i=0;i<8-n;i++)
{
buff2[8-i]=0;
}
for (x=0;x<8;x++)
buff2[x]=buff2[x]^buff3[x];
des(buff2,num);
for (x=0;x<8;x++)
buff3[x]=buff2[x];
fwrite(buff2,8,1,fp2);
}
}
if (num==0)
{
while ((n=fread(buff2,sizeof(char),8,fp1))==8)
{
for (x=0;x<8;x++)
buff4[x]=buff2[x];
des(buff2,num);
for (x=0;x<8;x++)
buff2[x]=buff2[x]^buff3[x];
for (x=0;x<8;x++)
buff3[x]=buff4[x];
fwrite(buff2,8,1,fp2);
}
}
}
fclose(fp1);
fclose(fp2);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -