Z26上维吉尼亚和行置换的乘积密码体制

本文介绍了一个基于C++实现的密码生成及加密解密流程。该程序能够生成Vigenère密码和行置换密码的密钥,并进行多次加密与解密操作。适用于小写字母的加密解密场景。

首先生成维吉尼亚密码的密钥和行置换密码的密钥

输入m和n,行置换是用m*m矩阵每组做的,维吉尼亚的密钥长度为n

结果分别放在3个文本文件中

#include <iostream>
#include <cstring>
#include <math.h>
#include <fstream>
#include <time.h>
#include <cstdlib>

using namespace std;

int main()
{
    srand(time(NULL));
    int m,n;
    cin>>m>>n;
    char k[1000];
    ofstream store_vegenere_key("vegenere_key.txt");
    //生成Vigenere密钥
    for(int i=0;i<n;i++)
    {
        k[i]=rand()%26+'a';
    }
    store_vegenere_key.write(k,n);
    store_vegenere_key.close();


    //生成rowPermutation密钥
    //生成置换密钥
    ofstream store_rowPermutation_incode_key("rowPermutation_encode_key.txt");
    ofstream store_rowPermutation_decode_key("rowPermutation_decode_key.txt");

    int incode_order[m];
    int decode_order[m];
    memset(incode_order,-1,sizeof(incode_order));
    int count=0;
    int index;
    while(1)
    {
        index=rand()%m;
        if(incode_order[index]==-1)
        {
            incode_order[index]=count;
            decode_order[count]=index;
            count++;
        }
       // cout<<count<<endl;
        if(count==m)break;
    }
    for(int i=0;i<m;i++)
    {
        store_rowPermutation_incode_key<<incode_order[i]<<" ";
        store_rowPermutation_decode_key<<decode_order[i]<<" ";
    }
    store_rowPermutation_incode_key.close();
    store_rowPermutation_decode_key.close();
    return 0;
}

 

将生成的3个密钥txt文本文件放在同一目录下

输入加密轮数t,读明文"in.txt"

输入1加密 结果放在“encode.txt”  输入2解密,结果放在"decode.txt"中

 

因为坑爹作业统计需要,只做了a-z的小写英文字母的加密解密。

#include <iostream>
#include <cstring>
#include <math.h>
#include <fstream>
#include <time.h>
#include <cstdlib>

using namespace std;

void encode(char *p,char *vigenere_key,int n,int *rowEncode,int m,ofstream &out_c,int t)
{
//先 维吉尼亚加密
    int total=m*m;
    while(t--)
    {
        int index=0;
        for(int i=0; i<total; i++)
        {
            p[i]=((p[i]-97)+(vigenere_key[index++]-97))%26+97;
            if(index==n)index=0;
        }
//后 行置换加密
        char temp[m][m];
        int x=0,y=0;
        for(int i=0; i<total; i++)
        {
            temp[x][y++]=p[i];
            if(y==m)
            {
                y=0;
                x++;
            }
        }
        char c_matrix[m][m];
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<m; j++)
            {
                c_matrix[j][rowEncode[i]]=temp[j][i];
            }
        }
        int num=0;
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<m; j++)
            {
                p[num++]=c_matrix[j][i];
            }
        }

    }
    for(int i=0; i<total; i++)
    {
        out_c<<p[i];
    }
}

void decode(char *c,char *vigenere_key,int n,int *rowDecode,int m,ofstream &out_r,int t)
{
//行置换解密
    char temp[m][m];
    int total=m*m;
    while(t--)
    {
        int x=0,y=0;
        for(int i=0; i<total; i++)
        {
            temp[x++][y]=c[i];
            if(x==m)
            {
                x=0;
                y++;
            }
        }
        char r_matrix[m][m];
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<m; j++)
            {
                r_matrix[j][rowDecode[i]]=temp[j][i];
            }
        }
        int num=0;
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<m; j++)
            {
                c[num++]=r_matrix[i][j];
            }
        }
//维吉尼亚解密
        int index=0;
        for(int i=0; i<total; i++)
        {
            int sum=c[i]-vigenere_key[index++];
            if(index==n)index=0;
            while(sum<0)
            {
                sum+=26;
            }
            c[i]=sum%26+97;
        }
    }
    for(int i=0; i<total; i++)
    {
        out_r<<c[i];
    }
} 

int main()
{
    int t;
    cin>>t;
//读入vigenere密钥
    char vigenere_key[1000];
    ifstream in_key1("vegenere_key.txt");
    in_key1.read(vigenere_key,1000);
    int vigenere_key_len=in_key1.gcount();
    in_key1.close();

    int choice;
    cin>>choice;
    switch(choice)
    {
    case 1:
    {
//加密
//读入rowPermutation 加密密钥
        int rowEncode[100];
        int temp;
        ifstream in_key2("rowPermutation_encode_key.txt");
        int num=0;
        while(in_key2>>temp)
        {
            rowEncode[num++]=temp;
        }
        in_key2.close();
//读入明文,结果放在"encode.txt"中
        ifstream in_p("in.txt");
        ofstream out_c("encode.txt");
        char p[num*num];

        while(1)
        {
            memset(p,0,sizeof(p));
            in_p.read(p,num*num);
            if(in_p.gcount()<num*num)
            {
                out_c<<p;
                break;
            }
            encode(p,vigenere_key,vigenere_key_len,rowEncode,num,out_c,t);
        }
        in_p.close();
        out_c.close();
        break;
    }
    case 2:
    {
//解密
//读入rowPermutation 解密密钥
        int rowDecode[100];
        int temp;
        ifstream in_key3("rowPermutation_decode_key.txt");
        int num=0;
        while(in_key3>>temp)
        {
            rowDecode[num++]=temp;
        }
        in_key3.close();
//读入密文
        ifstream in_c("encode.txt");
        ofstream out_r("decode.txt");
        char c[num*num];
        while(1)
        {
            memset(c,0,sizeof(c));
            in_c.read(c,num*num);
            if(in_c.gcount()<num*num)
            {
                out_r<<c;
                break;
            }
            decode(c,vigenere_key,vigenere_key_len,rowDecode,num,out_r,t);
        }
        in_c.close();
        out_r.close();
        break;
    }
    default:
        break;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值