为了更好地理解DES算法,美国圣克拉拉大学的Edward Schaefer教授于1996年开发了Simplfied DES方案,简称S-DES方案。它是一个供教学而非安全使用的加密算法,它与DES的特性和结构类似,但参数小,明文分组为8位,主密钥分组为10位,采用两轮选代。
S-DES的加密原理图如上图所示
S-DES的具体实现步骤:
S-DES的f函数结构如上图所示
S-DES的f函数结构的具体实现步骤:
S-DES的S盒
S1 S 1 | 00 00 | 01 01 | 10 10 | 11 11 | S2 S 2 | 00 00 | 01 01 | 10 10 | 11 11 |
00 00 | 01 | 00 | 11 | 10 | 00 00 | 00 | 01 | 10 | 11 |
01 01 | 11 | 10 | 01 | 00 | 01 01 | 10 | 00 | 01 | 11 |
10 10 | 00 | 10 | 01 | 11 | 10 10 | 11 | 10 | 01 | 00 |
11 11 | 11 | 01 | 00 | 10 | 11 11 | 10 | 01 | 00 | 11 |
S-DES解密的步骤:
如设主密钥 K K =1010000010,用S-DES加密明文字母 C C
所以我们可以将其程序化
#include
#include
#include
#include
using namespace std;
int S1[4][4][2]={{{0,1},{0,0},{1,1},{1,0}},
{{1,1},{1,0},{0,1},{0,0}},
{{0,0},{1,0},{0,1},{1,1}},
{{1,1},{0,1},{0,0},{1,0}}};
int S2[4][4][2]={{{0,0},{0,1},{1,0},{1,1}},
{{1,0},{0,0},{0,1},{1,1}},
{{1,1},{1,0},{0,1},{0,0}},
{{1,0},{0,1},{0,0},{1,1}}};
void createkey(int k[11],int k1[9],int k2[9])
{
int temp[11];
temp[1]=k[3],temp[2]=k[5],temp[3]=k[2],temp[4]=k[7],temp[5]=k[4],temp[6]=k[10],temp[7]=k[1],temp[8]=k[9],temp[9]=k[8],temp[10]=k[6];
int l[6],r[6];
for(int i=1;i<=5;i++)
l[i]=temp[i],r[i]=temp[i+5];
int x1,x2,x3,x4;
x1=l[1],x2=r[1];
for(int i=2;i<=5;i++)
l[i-1]=l[i],r[i-1]=r[i];
l[5]=x1;
r[5]=x2;
for(int i=1;i<=5;i++)
temp[i]=l[i],temp[i+5]=r[i];
k1[1]=temp[6],k1[2]=temp[3],k1[3]=temp[7],k1[4]=temp[4],k1[5]=temp[8],k1[6]=temp[5],k1[7]=temp[10],k1[8]=temp[9];
x1=l[1],x2=l[2],x3=r[1],x4=r[2];
for(int i=2;i<=5;i++)
l[i-2]=l[i],r[i-2]=r[i];
l[4]=x1,l[5]=x2;
r[4]=x3,r[5]=x4;
for(int i=1;i<=5;i++)
temp[i]=l[i],temp[i+5]=r[i];
k2[1]=temp[6],k2[2]=temp[3],k2[3]=temp[7],k2[4]=temp[4],k2[5]=temp[8],k2[6]=temp[5],k2[7]=temp[10],k2[8]=temp[9];
}
void f(int R[],int K[])
{
int temp[9];
temp[1]=R[4],temp[2]=R[1],temp[3]=R[2],temp[4]=R[3],temp[5]=R[2],temp[6]=R[3],temp[7]=R[4],temp[8]=R[1];
for(int i=1;i<=8;i++)
temp[i]=temp[i]^K[i];
int s1[5],s2[5];
for(int i=1;i<=4;i++)
s1[i]=temp[i],s2[i]=temp[i+4];
int x1=S1[s1[1]*2+s1[4]][s1[2]*2+s1[3]][0],x2=S1[s1[1]*2+s1[4]][s1[2]*2+s1[3]][1];
int x3=S2[s2[1]*2+s2[4]][s2[2]*2+s2[3]][0],x4=S2[s2[1]*2+s2[4]][s2[2]*2+s2[3]][1];
R[1]=x2,R[2]=x4,R[3]=x3,R[4]=x1;
}
void Encode(int x,int k1[],int k2[])
{
int ming[9];
for(int i=8;i>=1;i--)
{
ming[i]=x%2;
x/=2;
}
int temp[9];
temp[1]=ming[2],temp[2]=ming[6],temp[3]=ming[3],temp[4]=ming[1],temp[5]=ming[4],temp[6]=ming[8],temp[7]=ming[5],temp[8]=ming[7];
int L0[5],R0[5],L1[5],R1[5],L2[5],R2[5];
for(int i=1;i<=4;i++)
L0[i]=temp[i],R0[i]=temp[i+4];
memcpy(L1,R0,sizeof(L1));
f(R0,k1);
for(int i=1;i<=4;i++)
R1[i]=L0[i]^R0[i];
memcpy(R2,R1,sizeof(R2));
f(R1,k2);
for(int i=1;i<=4;i++)
L2[i]=L1[i]^R1[i];
temp[1]=L2[4],temp[2]=L2[1],temp[3]=L2[3],temp[4]=R2[1],temp[5]=R2[3],temp[6]=L2[2],temp[7]=R2[4],temp[8]=R2[2];
printf("加密后二进制为:");
int ans=0;
for(int i=1;i<=8;i++)
{
ans+=temp[i]*(1<<(8-i));
printf("%d",temp[i]);
}
printf("\n");
printf("加密后对应字母为:%c\n",ans);
}
void Decode(int x,int k1[],int k2[])
{
int ming[9];
for(int i=8;i>=1;i--)
{
ming[i]=x%2;
x/=2;
}
int temp[9];
temp[1]=ming[2],temp[2]=ming[6],temp[3]=ming[3],temp[4]=ming[1],temp[5]=ming[4],temp[6]=ming[8],temp[7]=ming[5],temp[8]=ming[7];
int L0[5],R0[5],L1[5],R1[5],L2[5],R2[5];
for(int i=1;i<=4;i++)
L2[i]=temp[i],R2[i]=temp[i+4];
memcpy(R1,R2,sizeof(R1));
f(R2,k2);
for(int i=1;i<=4;i++)
L1[i]=L2[i]^R2[i];
memcpy(R0,L1,sizeof(R0));
f(L1,k1);
for(int i=1;i<=4;i++)
L0[i]=R1[i]^L1[i];
temp[1]=L0[4],temp[2]=L0[1],temp[3]=L0[3],temp[4]=R0[1],temp[5]=R0[3],temp[6]=L0[2],temp[7]=R0[4],temp[8]=R0[2];
printf("解密后二进制为:");
int ans=0;
for(int i=1;i<=8;i++)
{
ans+=temp[i]*(1<<(8-i));
printf("%d",temp[i]);
}
printf("\n");
printf("解密后对应字母为:%c\n",ans);
}
int main()
{
int k[11],k1[9],k2[9];
printf("请输入主密钥K:");
for(int i=1;i<=10;i++)
scanf("%1d",&k[i]);
createkey(k,k1,k2);
char ming[2];
printf("请输入明文:");
scanf("%s",ming);
Encode(ming[0],k1,k2);
printf("请输入密文:");
char mi[2];
scanf("%s",mi);
Decode(mi[0],k1,k2);
return 0;
}