加密算法编程实验

天津机电职业技术学院教师备课纸

实验五 加密算法编程

一、实验目的

通过C语言编程实现替代加密算法,加深对古典密码体制的了解。

二、实验环境

1.安装Windows XP系统的计算机

2.WinTC

三、实验理论基础

凯撒密码(caeser)是罗马扩张时期朱利斯?凯撒(Julius Caesar)创造的,用于加密通过信使传递的作战命令。它将字母表中的字母移动一定位置而实现加密。 凯撒密码的加密算法极其简单。其加密过程如下:

在这里,明文记为m,密文记为c,加密变换记为E(k1,m)(其中k1为密钥),解密变换记为D(k2,m)(k2为解密密钥)(在这里k1=k2,不妨记为k)。凯撒密码的加密过程可记为如下一个变换:

c≡m+k mod n (其中n为基本字符个数)

同样,解密过程可表示为:

m≡c+k mod n (其中n为基本字符个数)

对于计算机而言,n可取256或128,m、k、c均为一个8bit的二进制数。显然,这种加密算法极不安全,即使采用穷举法,最多也只要255次即可破译。当然,究其本身而言,仍然是一个单表置换,因此,频率分析法对其仍是有效的。

四、实验内容

凯撒密码及其破解的编程实现

1

天津机电职业技术学院教师备课纸 #include <stdio.h>

main()

{

char M[100];

char C[100];

int K=3,i;

printf("please input chars:\n");

gets(M);

for(i=0;M[i]!='\0';i++)

C[i]=(M[i]-'a'+K)%26+'a';

C[i]='\0';

printf("The result is:\n%s\n",C);

getch();

}

2

 

第二篇:计算机加密算法实验一

实验一、密码学基础实验

一、实验目的

    通过实现简单的古典密码算法,理解密码学的相关概念如明文(plaintext)、密文(ciphertext)、加<a href=” www.scsiot.com”>密密钥</a>(encryption key)、解密密钥(decryption key)、加密算法(encryption algorithm)、解密算法(decryption algorithm)等。

       (1)通过这个上机训练,让学生深刻了解DES、RSA的运行原理。掌握使用DES、RSA算法对实际的数据进行加密和解密。

       (2)通过这个上机训练,使学<a href=” www.scsiot.com”>生掌握常</a>用密码软件(PGP、SSH)下载、安装、使用

二、实验内容

【实验项目1】

l  用C\C++语言实现仿射变换(Affine)加/解密算法;

l  用C\C++语言实现统计26个英文字母出现的频率的程序;

l  利用仿射变换加/解密程序对一段较长的英文文章进行加密,再利用统计软件对明文和密文中字母出现的频率进行统计并作对比,观察有什么规律。

    放射变换:

加密

解密

其中a, b为密钥,,且gcd(a, 26)=1

实验要求:加/解密程序对任意满足条件的a、b都能够处理。

1.1实验步骤

(1)统计26个英文字母出现的频率的程序

#include<iostream>

#include<fstream>

#include<vector>

using namespace std;

void main(){

     ifstream in("a.txt");

        vector<int> s;

        vector<int> n(26,0);

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

               s.push_back(97+i);

        for(char x;in>>x; )

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

                      if(int(x)==s[i]){

                             n[i]++;}

        float sum=0.0;

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

        sum+=n[j];

        cout<<"统计结果如下:"<<endl;

    for(int k=0;k<26;++k){

              // n[k]=n[k]/sum;

               cout<<' '<<char(k+97)<<"出现的概率为:"<<n[k]/sum<<endl;

               //cout<<n[k]<<endl;

        }

(2)仿射变换加/解密程序对一段较长的英文文章进行加密

#include<iostream>

#include<fstream>

#include<vector>

using namespace std;

//////////判断两个数是不是互素(辗转相除)////////

bool gcd(int a){

       int f=26,g,r;

       g=a;

       do{

              r=f%g;

              f=g;

              g=r;

       }while(r);

       if(f==1)

              return 1;

       else

              return 0;

}

//////////////////求逆//////

int inv(int a){

       int x,i;

       for(i=1;i<=30;++i)

              if((26*i+1)%a==0)

              {

                     x=(26*i+1)/a;break;}

              return x;

}//////////////////////////////////////////////////////////

void main(){

       cout<<"请你选择操作密码的方式:"<<endl<<"   0—表示加密 "<<endl<<"   1—表示解密 "<<endl;

       int z;

       cin>>z;

       if(z==0||z==1)             

       {

//////////////////////////////////////////

       cout<<"请输入密钥a和b:"<<endl;

       int a,b;

       cin>>a>>b;

       if((a<1||a>25)||(b<0||b>25))

              cout<<"a,b的输入范围有错!"<<endl;

       else

              if(gcd(a)==0)

                     cout<<"密钥a有误,与26不互素"<<endl;

              else

              {

                     if(z==0)////加密算法

                     {

               ifstream in("a.txt");

                  ofstream out("b.txt");

                  vector<int> s;

                  for(char x;in>>x; )

                    s.push_back(int(x));

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

                        {  

                        s[i]=(a*(s[i]-97)+b)%26;

                        out<<char(s[i]+97)<<' ';

                        }out<<endl;cout<<"加密成功!明文请见“b.txt”"<<endl;

                     }    

            else////解密算法

                     {

                            ifstream in("b.txt");

                   ofstream out("a.txt");

                  vector<int> s;

                   for(char x;in>>x; )

                     s.push_back(int(x));

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

                            {  

                                   s[i]=inv(a)*(s[i]-97-b+26)%26;

                          out<<char(s[i]+97)<<' ';

                            }out<<endl;cout<<"解密成功!密文请见“a.txt”"<<endl;

                     }

              }

////////////////////////////////////////

       }

       else

              cout<<"所选操作无效!"<<endl;

}

}

1.2实验结果及分析

该程序是对文件进行操作,结果如下:

(1)   统计26个英文字母出现的频率的程序

 (2) 仿射变换加/解密程序对一段较长的英文文章进行加密

【实验项目2】利用C\C++实现RSA算法的加、解密运算。

具体包括:

1)      利用扩展的EUCLID计算 a mod n 的乘法逆元;

2)      Miller-Rabin素性测试算法对一个给定的大数进行测试;

3)      实现的运算,并计算

4)      利用Fermat定理手工计算,并与3)计算的结果对比;

5)      实现RSA算法。并对"I LOVE THE PEOPLE'S REPUBLIC OF CHINA"加解密。说明:为了方便实现,分组可以小一点,比如两个字母一组。

2.1实验步骤

#include <iostream>

#include <vector>

#include <string>

using namespace std;

int Euclid(int a,int n)//n大于a

{

       int x,y,r;

       x=n;y=a;

       for(int i=0;;)

       {

       if(y==0)

              return x;

       if(y==1)

              return y;

    r=x%y;

       x=y;

       y=r;

       }

}

double extenEuclid(double a,double n)//利用扩展的EUCLID计算 a mod n 的乘法逆元

{

       double x1=1,x2=0,x3=n,y1=0,y2=1,y3=a,Q;

       double t1,t2,t3;

       for(int i=0;;)

       {

           if(y3==0)

              {

                  return x3;

                  cout<<"no reverse"<<endl;

              }

           if(y3==1)

                  return y2;

           Q=int(x3/y3);

        t1=x1-Q*y1;

           t2=x2-Q*y2;

           t3=x3-Q*y3;

           x1=y1;x2=y2;x3=y3;

           y1=t1;y2=t2;y3=t3;

       }

}

bool Rabin(int a,int n)//Miller-Rabin素性测试算法对一个给定的大数进行测试

{

       vector<int> b;

       unsigned int N=n-1;

       for(int i=0,j=1;; i++)

       {

              if(j>N)

                     break;

              if( (N>> i) & (unsigned int)1 )

                  b.push_back(1);

              else

                     b.push_back(0);

              j*=2;

       }//将n-1表示成二进制形式

       for(int k=0;k<b.size();k++)

              cout<<b[k];

       cout<<endl;

      

       int d=1,x=0;

       for(int ii=b.size()-1;ii>=0;ii--)

       {

              x=d;

              d=(d*d)%n;

              if(d==1&&x!=1&&x!=n-1)

                     return false;

              if(b[ii]==1)

                     d=(d*a)%n;

       }

       if(d!=1)

              return false;

       return true;

}

double quickindex1(double a,double m,double n)//实现a^m mod n 的运算

{

       vector<int> b;

       unsigned double N=m;

       for(int ii=0,j=1;;ii++)

       {

              if(j>N)

                     break;

              if((N>>ii)& (unsigned double) 1)

                     b.push_back(1);

              else

                     b.push_back(0);

              j*=2;

       }    

       double c=0,d=1;

       for(int i=b.size()-1;i>=0;i--)

       {

              c*=2;

              d=(d*d)-int((d*d)/n)*n;

              if(b[i]==1)

              {

                     c+=1;

                     d=(d*a)-int((d*a)/n)*n;

                    

              }

       }

       return d;

}

void transfer(char cypher[],double c[])

{

       int m[100]={0};

       for(int i=0,j=0;cypher[j]!='\0';i+=2)

       {

              if(cypher[j]==' ')

              {

                     m[i]=0;m[i+1]=0;

              }

              else

              {

                     m[i]=cypher[j]-64;

                     if(m[i]<10)

                     {

                            m[i+1]=m[i];

                            m[i]=0;

                     }

                     else

                     {

                            m[i+1]=m[i]%10;

                            m[i]=m[i]/10;

                     }

              }

              j++;

       }

       for(int k2=0;k2<2*strlen(cypher);k2++)

              cout<<m[k2];

       cout<<endl;

       //int c[100]={0};

       for(int k=0,n=0;k<2*strlen(cypher);k+=4)

       {

              c[n]=m[k]*1000+m[k+1]*100+m[k+2]*10+m[k+3];

              n++;

       }

for(;c[n-1]<1000;)//最后一个数填充零,不过此例可要可不要

              c[n-1]*=10;

}

void main()

{

       double c[100]={0};

       double a[100]={0};

       double b[100]={0};

       char cypher[]="I LOVE THE PEOPLE'S REPUBLIC OF CHINA";

//对“我爱中华人民共和国”加解密

    

       transfer(cypher,c);//字母变数字的过程

       for(int k1=0;c[k1]!='\0';k1++)

              cout<<c[k1]<<" ";

       //选取两个素数p=563,q=823

       double n=0, fn=0, p=563,q=823,d=0;

       n=p*q;fn=(q-1)*(p-1);

       //选e与fn互素

       for(double e=2;e<fn;e+=3)

       {

              if(Euclid(e,fn)==1)

                     break;

       }

       d=extenEuclid(e,fn);

      

    cout<<endl<<"密码和密钥e d and n:";

       cout<<e<<" "<<d<<" "<<n<<endl;

       //加密过程

       cout<<endl<<"加密:";

       for(int i=0;c[i]!='\0';i++)

       {

              a[i]=quickindex1(c[i],e,n);

              cout<<a[i]<<" ";

       }

       cout<<endl<<"解密:";

       //解密过程

       for(int j=0;a[j]!='\0';j++)

       {

              b[j]=quickindex1(a[j],d,n);

              cout<<b[j]<<" ";

       }

    cout<<endl;

}

2.2实验结果及分析

【实验项目3】

常用密码软件(PGP、SSH)下载、安装、使用

相关推荐