问题描述:根据输入的10bit主密钥,将输入的8bit明文(密文)加密(解密)成8bit的密文(明文)。
例:输入:明文0100 0011
主密钥:10100 00010
输出:密文0 1 0 0 0 1 0 0
将S盒定义修改为你所使用的课本上定义即可!!!(即修改以下代码块中数组的值)
加密示意图:
f函数求解示意图:
子秘钥求解示意图:
代码:
#define _CRT_SECURE_NO_WARNINGS 1
//S-DES密码体制
#include<stdio.h>
//菜单
void menu() {
printf("------- S-DES --------\n");
printf("------- 1. 加密 --------\n");
printf("------- 2. 解密 --------\n");
printf("------- 0. 退出 --------\n");
}
//f函数
int f(int R[4], int key[8]) {//传R0和key1或R1和key2
int s[4] = { 0 }, s1[4] = { 0 }, s2[4] = { 0 }, f[4] = { 0 };
int temp = 0;
//定义两个s盒
/*int sh1[4][4] = { {1,0,3,2},
{3,2,1,0},
{0,2,1,3},
{3,1,0,2}
};
int sh2[4][4] = { {0,1,2,3},
{2,0,1,3},
{3,2,1,0},
{2,1,0,3}
};*/
int sh1[4][4] = { {1,0,2,3},
{2,3,0,1},
{0,1,3,2},
{3,2,1,0}
};
int sh2[4][4] = { {0,1,2,3},
{2,0,3,1},
{1,3,0,2},
{3,2,1,0}
};
//E/P扩位及置换 4 1 2 3 2 3 4 1
int R0[8] = { 0 };
int ret = 0;
R0[0] = R[3];
R0[1] = R[0];
R0[2] = R[1];
R0[3] = R[2];
R0[4] = R[1];
R0[5] = R[2];
R0[6] = R[3];
R0[7] = R[0];
//异或
for (int i = 0; i < 8; i++)
{
ret = R0[i] ^ key[i];
R0[i] = ret;
}
//分为左右两个部分s1、s2
for (int i = 0; i < 4; i++)
{
s1[i] = R0[i];
s2[i] = R0[i + 4];
}
//查找对应s盒的数据
s[0] = s1[0] * 2 + s1[3];
s[1] = s1[1] * 2 + s1[2];
temp = sh1[s[0]][s[1]];
s[0] = temp / 2;
s[1] = temp % 2;
s[2] = s2[0] * 2 + s2[3];
s[3] = s2[1] * 2 + s2[2];
temp = sh2[s[2]][s[3]];
s[2] = temp / 2;
s[3] = temp % 2;
//p4置换 2 4 3 1
f[0] = s[1];
f[1] = s[3];
f[2] = s[2];
f[3] = s[0];
return f;
}
//加密与解密(input==1时为加密算法,input==2时是解密算法)
void encryption_and_decryption(int input) {
//加密解密变量定义
int m[8] = { 0 };//存贮明文(当是解密算法是用作存贮密文)
int c1[8] = { 0 };//存贮IP置换前的密文
int c[8] = { 0 };//存贮密文
int m1[8] = { 0 };//IP置换后
int L0[4] = { 0 }, R0[4] = { 0 };//定义L0和R0
int L1[4] = { 0 }, R1[4] = { 0 };
int L2[4] = { 0 }, R2[4] = { 0 };
//子秘钥变量定义
int key[10] = { 0 };
int p10[10] = { 0 };//存贮p10置换
int LS_1[10] = { 0 };
int LS_2[10] = { 0 };
int key1[8] = { 0 }, key2[8] = { 0 };
//f函数变量定义
int temp = 0;
int* pf = NULL;
//加密算法
if (input == 1) {
printf("请输入二进制明文(以空格隔开):");
}
//解密算法
else
{
printf("请输入二进制密文(以空格隔开):");
}
for (int i = 0; i < 8; i++)
{
scanf_s("%d", &m[i]);
}
//IP置换 2 6 3 1 4 8 5 7
m1[0] = m[1];
m1[1] = m[5];
m1[2] = m[2];
m1[3] = m[0];
m1[4] = m[3];
m1[5] = m[7];
m1[6] = m[4];
m1[7] = m[6];
//分为两部分
for (int i = 0; i < 4; i++)
{
L0[i] = m1[i];
R0[i] = m1[i + 4];
L1[i] = m1[i + 4];//L1与R0相同
}
//求子秘钥
printf("请输入主密钥(以空格隔开):");
for (int i = 0; i < 10; i++)
{
scanf_s("%d", &key[i]);
}
//p10置换 3 5 2 7 4 10 1 9 8 6
p10[0] = key[2];
p10[1] = key[4];
p10[2] = key[1];
p10[3] = key[6];
p10[4] = key[3];
p10[5] = key[9];
p10[6] = key[0];
p10[7] = key[8];
p10[8] = key[7];
p10[9] = key[5];
//左移一位
for (int i = 0; i < 5; i++)
{
LS_1[i] = p10[(i + 1) % 5];
LS_1[i + 5] = p10[((i + 1) % 5) + 5];
}
//p8置换 6 3 7 4 8 5 10 9 求key1
key1[0] = LS_1[5];
key1[1] = LS_1[2];
key1[2] = LS_1[6];
key1[3] = LS_1[3];
key1[4] = LS_1[7];
key1[5] = LS_1[4];
key1[6] = LS_1[9];
key1[7] = LS_1[8];
//左移两位
for (int i = 0; i < 5; i++)
{
LS_2[i] = LS_1[(i + 2) % 5];
LS_2[i + 5] = LS_1[((i + 2) % 5) + 5];
}
//p8置换 6 3 7 4 8 5 10 9 求key2
key2[0] = LS_2[5];
key2[1] = LS_2[2];
key2[2] = LS_2[6];
key2[3] = LS_2[3];
key2[4] = LS_2[7];
key2[5] = LS_2[4];
key2[6] = LS_2[9];
key2[7] = LS_2[8];
//加密先用key1
if (input == 1) {
pf = f(R0, key1);
}
//解密先用key2
else
{
pf = f(R0, key2);
}
//f函数与L0异或
for (int i = 0; i < 4; i++)
{
temp = L0[i] ^ *(pf + i);
R1[i] = temp;
R2[i] = temp;//R2和R1一样
}
//加密
if (input == 1) {
pf = f(R1, key2);
}
//解密
else
{
pf = f(R1, key1);
}
for (int i = 0; i < 4; i++)
{
temp = L1[i] ^ *(pf + i);
L2[i] = temp;
}
//将上述求得的L2和R2进行拼接合并到c1
for (int i = 0; i < 4; i++)
{
c1[i] = L2[i];
c1[i + 4] = R2[i];
}
//IP逆置换 4 1 3 5 7 2 8 6
c[0] = c1[3];
c[1] = c1[0];
c[2] = c1[2];
c[3] = c1[4];
c[4] = c1[6];
c[5] = c1[1];
c[6] = c1[7];
c[7] = c1[5];
//分不同情况打印
if (input == 1) {
printf("密文是:");
}
else
{
printf("明文是:");
}
for (int i = 0; i < 8; i++)
{
printf("%d ", c[i]);
}
printf("\n");
}
void test() {
int input = 0;
do {
menu();
printf("请选择:->");
scanf_s("%d", &input);
switch (input)
{
case 1:
encryption_and_decryption(input);
break;
case 2:
encryption_and_decryption(input);
break;
case 0:
printf("已退出加密解密系统\n");
break;
default:
printf("输入有误,请重新输入!\n");
break;
}
} while (input);
}
int main() {
test();
return 0;
}
运行结果截图:
如果内容对你有帮助,关注我,给我点个小小的赞吧!
若内容有误,请指正并多多包容,谢谢。