zoukankan      html  css  js  c++  java
  • 累死人之希尔加密

    #include <iostream>
    #include <vector>
    #include<string.h>
    #include<stdio.h>
    #define N 5
    using namespace std;
    
    int exgcd(int A,int &x,int B,int &y)
    {
        int x1,y1,x0,y0;
        x0=1;y0=0;
        x1=0;y1=1;
        int r=(A%B+B)%B;
        int q=(A-r)/B;
        x=0;y=1;
        while(r)
        {
            x=x0-q*x1;
            y=y0-q*y1;
            x0=x1;
            y0=y1;
            x1=x;y1=y;
            A=B;B=r;r=A%B;
            q=(A-r)/B;
        }
        return B;
    }
    int modq(int a,int n,int x,int y)
    {
    int b=1;
       int d=exgcd(a,x,n,y);
            if(b%d==0)
            {
                x=(x%(n/d)+n/d)%(n/d);
                if(!x)x++;
                return x;
            }
            else printf("Not Exist
    ");
    }
    //计算矩阵的行列式 
    int getA(int A[N][N],int n)
    {
        if(n==1)   return A[0][0];
        int num=0;
        int temp[N][N]={0.0};
        int i,j,k;
        for(i=0;i<n;i++)
            {
                for(j=0;j<n-1;j++)
                    {
                        for(k=0;k<n-1;k++)
                        {
                            if(k>=i)   temp[j][k]=A[j+1][k+1];
                            else       temp[j][k]=A[j+1][k];
                        }
                    }
                int t=getA(temp,n-1);
                if(i%2==0)  num+=A[0][i]*t;
                else        num-=A[0][i]*t;
                }
        return num%26;
    }
    //求矩阵的伴随矩阵 
    void getAstart(int A[N][N],int n,int newA[N][N]) 
    {
        if(n==1)
        {
            newA[0][0]=1;
            return;
        }
        int i,j,k,t;
        int temp[N][N];
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                for(k=0;k<n-1;k++)
                {
                    for(t=0;t<n-1;t++)
                    {
                        temp[k][t]=A[(k>=i)?k+1:k][(t>=j)? t+1:t];
                    }
                }
                newA[j][i]=(getA(temp,n-1));
                if((i+j)%2==1)  newA[j][i]=-newA[j][i];
                newA[j][i]=newA[j][i]%26;
                if(newA[j][i]<0)  newA[j][i]=(newA[j][i]+26)%26;
            }
        }
    }
    //求矩阵的逆
    void  getInverse(int A[N][N],int n,int I[N][N])
    {
        int t[N][N]={0.0};
        int flag=getA(A,n);
        int x,y;
        int e=modq(flag,26,x,y);
        if(e==0)  return;
        else
        {
            getAstart(A,n,t);
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    I[i][j]=(t[i][j]*e)%26;
                    if(I[i][j]<0)  
                        I[i][j]=(I[i][j]+26)%26;
                }
            }
        }
    } 
    
    int gcd(int m,int n)
    {
        int r=0;
        if(m==0||n==0)  return 0;
        if(m==1||n==1)  return 1;
        else
        {
            if(n>m)
            {
                int s=m;
                m=n;n=s;
            }    
        r=m%n;
        while(r!=0)
        {
            m=n;
            n=r;
            r=m%n;
            if(r==0)
                {
                    return n;
                }
            }
        }
    }
    
    bool IsInverse(int A[N][N],int n)//判断矩阵是否可作为密钥 
    {
        int t=getA(A,n);
        if(gcd(t,26)==1)  return true;
        else   return false;
    }
    vector<int> change1(string s) //将明文密文转化为字母表中的次序,A为0,依次类推 
     {
      vector<int>v;
      for(int i=0;i<s.size();i++)
      {
      if(s[i]>='A'&&s[i]<='Z')
      v.push_back(s[i]-'A');
      if(s[i]>='a'&&s[i]<='z')
      v.push_back(s[i]-'a');
    }
    return v;
     }
    
     string change2(vector<int>v)//将字母的次序转化为小写字母 
     {
      string s="";
      for(int i=0;i<v.size();i++) 
      {
      char a=v[i]+97;
      s+=a;
    }
    return s;
     }
     string change3(vector<int>v)//将字母的次序转化为大写字母 
     {
      string s="";
      for(int i=0;i<v.size();i++) 
      {
      char a=v[i]+65;
      s+=a;
    }
    return s;
     }
     
    //对明文进行加密
    void addcode(int A[N][N],string s){
        int length=s.length();
        vector<int> mingnum;
        mingnum=change1(s);
        int rows=length/N;
        int lines=N;
        int mingmatrix[rows][lines]={0.0};
        for(int i=0;i<length;i++){
            mingmatrix[i/5][i%5]=mingnum[i];
        }
        int mimatrix[rows][lines]={0.0};
        for(int i=0;i<rows;i++){
            for(int j=0;j<lines;j++){
                int temp=0;
                for(int k=0;k<lines;k++){
                    temp+=mingmatrix[i][k]*A[k][j];
                }
                mimatrix[i][j]=temp%26;
            }    
        }
        vector<int> minum;
        for(int i=0;i<rows;i++){
            for(int j=0;j<lines;j++){
                minum.push_back(mimatrix[i][j]);
            }
        }
        string miwen=change2(minum);
        cout<<"得到的密文"<<miwen<<endl;    
    } 
    
    void deaddcode(int A[N][N],string s){
        int D[N][N]={0.0};
        getInverse(A,5,D);
        int length=s.length();
        vector<int> minum;
        minum=change1(s);
        int rows=length/N;
        int lines=N;
        int mimatrix[rows][lines]={0.0};
        for(int i=0;i<length;i++){
            mimatrix[i/5][i%5]=minum[i];
        }
        int mingmatrix[rows][lines]={0.0};
        for(int i=0;i<rows;i++){
            for(int j=0;j<lines;j++){
                int temp=0;
                for(int k=0;k<lines;k++){
                    temp+=mimatrix[i][k]*D[k][j];
                }
                mingmatrix[i][j]=temp%26;
            }    
        }
        vector<int> mingnum;
        for(int i=0;i<rows;i++){
            for(int j=0;j<lines;j++){
                mingnum.push_back(mingmatrix[i][j]);
            }
        }
        string mingwen=change2(mingnum);
        cout<<"得到的明文"<<mingwen<<endl;    
    } 
     
     
     
    int main()
    {
    
        cout<<"请输入一个5阶密钥矩阵"<<endl;
        int ars[5][5];
        for(int i=0;i<5;i++){
            cout<<""<<i+1<<""<<endl; 
            for(int j=0;j<5;j++){
                cin>>ars[i][j];
            }
        }
        
        cout<<"请输入明文"<<endl;
        string mess;
        cin>>mess;
        addcode(ars,mess);
        
        cout<<"请输入密文"<<endl;
        string code;
        cin>>code;
        deaddcode(ars,code);
    } 

    其实老师让做的是变长的,我找了网上的代码,加密解密和它做的略有不同,不过除非是希尔加密否则求行列式不推荐这种做法,因为循环到了三层以上代码的可读性非常差,但是用这种方法求行列式的好处就是比较简单,推荐传一个二级指针进去进行行列式求解,较好理解,但对于希尔加密不适合,因为会在判断互素的时候损失精度。

  • 相关阅读:
    浅谈三层架构
    尺度空间(Scale space)理论
    漫游Kafka实现篇之消息和日志
    杭电 2095
    .net调用Outlook 批量发送邮件,可指定Outlook中的账号来发送邮件
    Java实现 蓝桥杯VIP 算法提高 计算时间
    Java实现 蓝桥杯VIP 算法提高 计算时间
    Java实现 蓝桥杯VIP 算法提高 计算时间
    Java实现 蓝桥杯VIP 算法提高 计算时间
    Java实现 蓝桥杯VIP 算法提高 最小乘积(提高型)
  • 原文地址:https://www.cnblogs.com/daremosiranaihana/p/10600604.html
Copyright © 2011-2022 走看看