古典密码附截图和C++代码

发布时间:2024-10-23

古典密码 密码学

实验一 实现一个多表古典加密和解密程序

计算机学院 信安08-3班 柴婷婷 08083708

一、实验目的:

掌握多表古典加密方法。

二、实验要求:

能用高级语言实现古典加密方法。

三、实验内容:

多表古典加密方法主要有Playfair体制、Vigenere体制、Beaufor体制、Vernam体制和Hill体制,用高级语言实现其中一种体制的加密和解密算法。

四、实验过程:

1、Vigenere加密解密:

维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。

#include <iostream>

#include <string>

using namespace std;

const int N=26;

char

v[N][N]={{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}}; int number(char x)//把行号字母对应到数字

{

char y='a';

for(int i=0;i<N;i++)

{

if(x==(y+i)) return i;

}

}

void encryption(string m,string k)//加密

{

cout<<"明文:";

cin>>m;

cout<<"密钥:";

cin>>k;

int mlen,klen;

mlen=m.length();

klen=k.length();

char *p,*q,*t;//明文,初始密钥,密钥串。把string换成char

古典密码 密码学

p=new char[m.length()+1];

strcpy(p,m.c_str());

q=new char[k.length()+1];

strcpy(q,k.c_str());

t=new char[m.length()+1];

int j=0;

for(int i=0;i<mlen;i++)

{

t[i]=q[j];

j++;

j=j%klen;

}//生成密钥

cout<<"密文:";

for(i=0;i<mlen;i++)

cout<<v[number(t[i])][number(p[i])];

cout<<endl;

}

void disencryption(string c,string k)//解密

{

cout<<"密文:";

cin>>c;

cout<<"密钥:";

cin>>k;

int clen,klen;

clen=c.length();

klen=k.length();

char *p,*q,*t;//密文,初始密钥,密钥串。把string换成char

p=new char[c.length()+1];

strcpy(p,c.c_str());

q=new char[k.length()+1];

strcpy(q,k.c_str());

t=new char[c.length()+1];

int j=0;

for(int i=0;i<clen;i++)

{

t[i]=q[j];

j++;

j=j%klen;

}//生成密钥

cout<<"明文:";

for(i=0;i<clen;i++)

for(int j=0;j<N;j++)

if(v[number(t[i])][j]==p[i]) {cout<<char(j+97);break;}

cout<<endl;

古典密码 密码学

}

int main()

{

for(int i=1;i<N;i++)

{

for(int j=0;j<N;j++)

{

v[i][j]=v[i-1][(j+1)%N];

}//方阵初始化

}

cout<<"欢迎使用Vigenere加密!"<<endl<<endl;

cout<<"请选择要进行的操作"<<endl;

int flag;

do{

cout<<"1.加密2.解密3.结束:"<<endl;

cin>>flag;

string m,k;

if(flag==1)encryption(m,k);

else if(flag==2) disencryption(m,k);

else if(flag!=1&&flag!=2&&flag!=3) cout<<"输入错误,请重新输入!";

}while(flag!=3);

return 0;

}

运行结果:

2、Playfair 加解密

古典密码 密码学

算法描述:Playfair密码出现于1854年,它依据一个5*5的正方形组成的密码表来编写,密码表里排列有25个字母。如果一种语言字母超过25个,可以去掉使用频率最少的一个。英语中z使用最少,可以去掉它。法语一般去掉w或k,德语则是把i和j合起来当成一个字母看待。英语中z使用最少,可以去掉它。

加密描述:第一步是编制密码表。在这个5*5的密码表中,共有5行5列字母。第一列(或第一行)是密钥,其余按照字母顺序。密钥是一个单词或词组,若有重复字母,可将后面重复的字母去掉。当然也要把使用频率最少的字母去掉。

第二步整理明文。将明文每两个字母组成一对。如果成对后有两个相同字母紧挨或最后一个字母是单个的,就插入一个字母X。

对明文加密规则如下:

1 若p1 p2在同一行,对应密文c1 c2分别是紧靠p1 p2 右端的字母。其中第一列被看做是最后一列的右方。如,按照前表,ct对应oc

2 若p1 p2在同一列,对应密文c1 c2分别是紧靠p1 p2 下方的字母。其中第一行被看做是最后一行的下方。

3 若p1 p2不在同一行,不在同一列,则c1 c2是由p1 p2确定的矩形的其他两角的字母(至于横向替换还是纵向替换要事先约好,或自行尝试)。如,按照前表,wh对应tk或kt。

对密文解密规则如下:

1 若c1 c2在同一行,对应明文p1 p2分别是紧靠c1 c2 左端的字母。其中最后一列被看做是第一列的左方。

2 若c1 c2在同一列,对应明文p1 p2分别是紧靠c1 c2 上方的字母。其中最后一行被看做是第一行的上方。

3 若c1 c2不在同一行,不在同一列,则p1 p2是由c1 c2确定的矩形的其他两角的字母。

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define NUM 1000

古典密码 密码学

int main()

{

int i,j,k=0,m,n,temp=0,length;

char key[NUM],voa[26];

char table[5][5];

char word[NUM];

printf("欢迎使用playfair加密!");

printf("密钥: ");

scanf("%s",key);

length=strlen(key);

for(i=0;i<length;i++)

{

if(key[i]=='j')

key[i]='i';

}

for(i=0;i<length;i++)

{

for(j=i+1;j<length;j++)

if(key[i]==key[j])

{

for(int t=j;t<length;t++)

{

key[t]=key[t+1];

}

j--;

length--;

}

if(j==1)

{

key[j]=0;

break;

}

}

for(i=0;i<26;i++)

{

voa[i]=65+i;

}

for(i=0;i<length;i++)

{

key[i]=key[i]-32;

}

古典密码 密码学

char p;

int count=0;

for(i=0;i<26;i++)

{

p=voa[i];

for(j=0;j<length;j++)

{

if(p==key[j])

{

key[i+length]=p;

count+=1;

break;

}

}

if(j==length)

{

key[i+length-count]=p;

}

}

int u=0;

for(i=0;i<26;i++)

{

if(key[i]=='J')

{

for(u=i;u<26;u++)

{

key[u]=key[u+1];

}

}

if(key[i]=='I')

key[i]='*';

}

temp=0;

for(i=0;i<5;i++)

{

for(j=0;j<5;j++)

{

古典密码 密码学

table[i][j]=key[j+temp];

printf("%c ",table[i][j]);

if(j==4)

{

temp+=5;

printf("\n");

}

}

}

printf("明文: ");

scanf("%s",word);

length=strlen(word);

int counter=0;

for(i=0;i<length;)

{

if(word[i]==word[i+1])

{

i+=1;

counter+=1;

}

else

i+=2;

}

for(i=0;i<length+counter;i+=2)

{

if(word[i]==word[i+1])

{

for(j=length+counter-1;j>i+1;j--)

{

word[j]=word[j-1];

}

word[i+1]='x';

}

}

length=length+counter;

古典密码 密码学

if(length%2!=0)

{

word[length]='x';

length+=1;

}

for(k=0;k<length;k++)

{

word[k]=word[k]-32;

}

for(i=0;i<length;i++)

{

if(word[i]=='I'||word[i]=='J')

{

word[i]='*';

}

}

count=0,k=0;

loop: for(i=0;i<5,k<length;i++)

{

for(j=0;j<5;j++)

{

for(m=0;m<5;m++)

{

for(n=0;n<5;n++)

{

if((table[i][j]==word[k])&&(table[m][n]==word[k+1])&&(i==m)) {

count=1;

word[k]=table[i][j+1];

word[k+1]=table[m][n+1];

if(j==4)

{

word[k]=table[i][0];

}

if(n==4)

{

古典密码 密码学

word[k+1]=table[m][0];

}

k+=2;

if(count==1)

{

goto loop;

}

}

else if((table[i][j]==word[k])&&(table[m][n]==word[k+1])&&(j==n)) {

count=1;

word[k]=table[i+1][j];

word[k+1]=table[m+1][n];

if(i==4)

{

word[k]=table[0][j];

}

if(m==4)

{

word[k+1]=table[0][n];

}

k+=2;

if(count==1)

{

goto loop;

}

}

else if((table[i][j]==word[k])&&(table[m][n]==word[k+1])&&(i!=m)&&(j!=n)) {

count=1;

word[k]=table[i][n];

word[k+1]=table[m][j];

k+=2;

if(count==1)

{

goto loop;

}

}

古典密码 密码学

}

}

}

}

printf("密文: ");

for(k=0;k<length;k++)

{

printf("%c ",word[k]);

}

printf("\n");

system("pause");

return 0;

}

运行结果:

3、Vernam(弗纳姆)加解密 主要步骤

1.按递增顺序把每个明文字母作为一个数字,A=0,B=1等等.

2.对输入密文中每一个字母做相同的处理.

3.将明文中的每个字母与密钥中的相应字母相加.

4.如果得到的和大于26,则从中减去26.

5.将和转化为字母,从而得到密文.

例如 明文: H O W A R E Y O U

古典密码 密码学

7 14 22 0 17 4 24 14 20

+ 2.密钥 N C B T Z Q A R X 13 2 1 19 25 16 0 17 23 3.初始和 20 16 23 19 42 20 24 31 43 4.大于25则模26 20 16 23 19 16 20 24 5 17

5.密文 U Q X T Q U Y F R

#include <iostream>

#include <string>

#include <vector>

using namespace std;

int main()

{

string plain,ciper,key;

int len; //长度三者一致

void change(string &, vector<int>&);//字符变数字

vector<int> encrypt_compute(vector<int> m,vector<int> k);//加密计算 vector<int> discrypt_compute(vector<int> c,vector<int> k);//解密计算 void re_change( vector<int>&,string &);//数字变字符

cout<<"欢迎使用Vernam加解密:"<<endl;

cout<<"====================="<<endl;

int flag; //操作标记

do

{

cout<<"请选择操作:1、加密 2、解密 3、结束:"<<endl; cin>>flag;

if(flag==1)

{

cout<<"请输入明文:";

cin>>plain;

cout<<"请输入相同长度的密钥:";

cin>>key;

len = plain.size();

vector<int> p,c,k; //存变换的数字

change(plain, p);

change(key, k); //字母->数字

c = encrypt_compute(p,k);

re_change(c,ciper); //数字->字母

cout<<"密文是:"<<ciper<<endl;

}

if(flag==2)

{

古典密码 密码学

cout<<"请输入密文:";

cin>>ciper;

cout<<"请输入相同长度的密钥:";

cin>>key;

len = ciper.size();

vector<int> p,c,k; //存变换的数字

change(ciper, c);

change(key, k); //字母->数字

p = discrypt_compute(c,k);

plain="";//清空明文原来的值

re_change(p,plain);

cout<<"明文是:"<<plain<<endl;

}

}while(flag!=3);

return 0;

}

void change(string &plain, vector<int>&number) //字母变数字 {

for (unsigned int i=0;i<plain.size();i++)

{

number.push_back(plain[i]-97); //a为0

}

}

vector<int> encrypt_compute(vector<int> m,vector<int> k) //加密计算 {

vector<int> sum;

for(unsigned int i=0; i<m.size(); i++)

{

sum.push_back((m[i]+k[i])%26);

}

return sum;

}

vector<int> discrypt_compute(vector<int> c,vector<int> k) //解密计算 {

vector<int> resum;

int temp;

for(unsigned int i=0; i<c.size(); i++)

{

temp = c[i]-k[i];

if(temp<0) temp+=26;

resum.push_back(temp);

}

古典密码 密码学

return resum;

}

void re_change( vector<int>& sum,string &c) //数字变字符 {

string temp;//用于处理insert函数变量传递

for (unsigned int i=0;i<sum.size();i++)

{

temp=sum[i]+97;

c.insert(i,temp);//a为0

}

}

运行结果:

古典密码附截图和C++代码.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:7 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:29元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219