1.设计一个凯撒加密函数,将明文加密成密文
void caesar_encr (char str[], int n)
str:明文字符串
n:加密时的偏移量,n>0 时后移 n 位,n<0 前移 n 位
设计相应的凯撒解密函数,将密文解密成明文
void caesar_decr (char str[], int n)
str:密文字符串
n:加密时的偏移量,n>0 时后移 n 位,n<0 前移 n 位
#include<iostream>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<cstdio>
#include<cstring>
using namespace std;
void caesar_encr (char str[], int n, char mode)
{
switch (mode)
{
case'a':
{
cout<<"该明文的暗文是:"<<endl;
int m=strlen(str);//获取str的长度
for(int i=0;i<m;i++)//历经字符串
{
if(str[i]>='0'&&str[i]<='9')
{
str[i]=str[i]+n;//偏移n长度
if(str[i]>'9')
{
str[i]=str[i]-10;
}
}
else if(str[i]>='A'&&str[i]<='Z')
{
str[i]=str[i]+n;
if(str[i]>'Z')
{
str[i]=str[i]-26;
}
}
else if(str[i]>='a'&&str[i]<='z')
{
str[i]=str[i]+n;
if(str[i]>'z')
{
str[i]=str[i]-26;
}
}
}
cout<<str ;//输出str
}
break;//mode a明文变暗文
case'b':
{
cout<<"该暗文的明文是:"<<endl;
int m=strlen(str);
for(int i=0;i<m;i++)
{
if(str[i]>='0'&&str[i]<='9')
{
str[i]=str[i]-n;
if(str[i]<'0')
{
str[i]=str[i]+10;
}
}
else if(str[i]>='A'&&str[i]<='Z')
{
str[i]=str[i]-n;
if(str[i]<'A')
{
str[i]=str[i]+26;
}
}
else if(str[i]>='a'&&str[i]<='z')
{
str[i]=str[i]-n;
if(str[i]<'a')
{
str[i]=str[i]+26;
}
}
}
cout<<str;
}
break;//mode b暗文变明文
}
}
int main()
{
int n;
char str[100],a;
cout<<"请输入明(暗)文:"<<endl;
gets(str);
cout<<"请输入偏移量:"<<endl;
cin>>n;
cout<< "请选择模式(明文转暗文输入a,暗文转明文输入b):"<<endl;
cin>>a;
caesar_encr (str,n,a);
return 0;
}
2.凯撒密码增强
凯撒密码中,所有字符的变化规律是一样的(均偏移固定的位数),这导致其安全性不高,
容易被破解。一个简单的改进,是将每个字符的变化变得不一致
以其中的数字变化为例
固定偏移中
0~9 分别映射为[3, 4, 5, 6, 7, 8, 9, 0, 1, 2]
均向后偏移 3 位,容易被猜出
在右图给出的随机偏移中
0~9 分别映射为[3, 5, 1, 0, 7, 8, 4, 6, 9, 2]
没有规律,难以破解
自己设计一种字母及数字的映射规则
根据该映射规则,实现加/解密操作
#include<iostream>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<cstdio>
#include<cstring>
using namespace std;
void caesar_encr_1 (char str[], char mode)
{
switch (mode)
{
case'a':
{
cout<<"该明文的暗文是:"<<endl;
int a[10]={'2','1','5','9','7','6','0','8','3','4'};
int b[26]={'S','Q','A','Z','X','W','E','D','C','V','R','F',
'T','B','G','H','Y','N','U','J','M','K','I','O','L','P'};
int c[26]={'z','a','x','q','c','v','b','n','m','s','d','f',
'g','h','j','k','l','w','e','r','t','y','u','i','o','p'};
int m=strlen(str);
for(int i=0;i<m;i++)
{
if(str[i]>='0'&&str[i]<='9')
{
int a_1=str[i]-'0';
str[i]=a[a_1];
}
else if(str[i]>='A'&&str[i]<='Z')
{
int b_1=str[i]-'A';
str[i]=b[b_1];
}
else if(str[i]>='a'&&str[i]<='z')
{
int c_1=str[i]-'a';
str[i]=c[c_1];
}
}
cout<<str ;//输出str
}
break;//mode a 明文变暗文
case'b':
{
cout<<"该暗文的明文是:"<<endl;
int a_1[10]={'2','1','5','9','7','6','0','8','3','4'};
int b_1[26]={'S','Q','A','Z','X','W','E','D','C','V','R','F',
'T','B','G','H','Y','N','U','J','M','K','I','O','L','P'};
int c_1[26]={'z','a','x','q','c','v','b','n','m','s','d','f',
'g','h','j','k','l','w','e','r','t','y','u','i','o','p'};
int m=strlen(str);
for(int i=0;i<m;i++)
{
if(str[i]>='0'&&str[i]<='9')
{
int a_2=str[i]-'0';
str[i]=a_1[a_2];
}
else if(str[i]>='A'&&str[i]<='Z')
{
int b_2=str[i]-'A';
str[i]=b_1[b_2];
}
else if(str[i]>='a'&&str[i]<='z')
{
int c_2=str[i]-'a';
str[i]=c_1[c_2];
}
}
cout<<str;
}
break;//mode b 暗文变明文
}
}
int main()
{
int n;
char str[100],a;
cout<<"请输入明(暗)文:"<<endl;
gets(str);
cout<< "请选择模式(明文转暗文输入a,暗文转明文输入b):"<<endl;
cin>>a;
caesar_encr_1 (str,a);
return 0;
}
读者也可以根据需求自己借助随机数组进行映射(每次传输的对应规制都不同),本文只是利用群举法做了一些映射,有一定的局限性。