精华内容
下载资源
问答
  • 多表代换密码的加密与解密
    2022-03-20 13:47:46
    #include <iostream>
    #include <vector>
    
    #define rap(a,b) for(int a=0;a<b;++a)
    using namespace std;
    string encypt(string m, double a[][4], double b[]) {
        string ans;
        for (int i = 0; i < 4; ++i) {
            int tmp = 0;
            for (int j = 0; j < 4; ++j) {
                tmp += a[i][j] * (m[j] - 'A');
            }
            tmp += b[i];
            ans += tmp % 26 + 'A';
        }
        return ans;
    }
    string decypt(string c, double a[][4], double b[]) {
        string ans;
        int cc[4];
        for (int i = 0; i < 4; ++i)cc[i] = (int)(c[i] - 'A' - b[i] + 26) % 26;
        for (int i = 0; i < 4; ++i) {
            int tmp = 0;
            for (int j = 0; j < 4; ++j) {
                tmp += a[i][j] * cc[j];
            }
            ans += tmp % 26 + 'A';
        }
        return ans;
    }
    int main() {
        double a[4][4] = {
        3,13,21,9,
        15,10,6,25,
        10,17,4,8,
        1,23,7,2
        };
        double b[4] = { 1,21,8,17 };
        string c = "PLEASE SEND ME TWO BOOKS MY CREDIT CARD NO IS SIX ONE TWO ONE THREE EIGHT SIX ZERO ONE SIX EIGHT FOUR NINE SEVEN ZERO TWO";
        //记录空格位置并去空格 
        vector<int>pos;
        int tmp = c.find(' ');
        while (tmp != -1)
        {
            pos.push_back(tmp);
            c.erase(tmp, 1);
            tmp = c.find(' ');
        }
        //加密 
        int i = 0;
        string m;
        while (i != c.size()) {
            m += encypt(c.substr(i, 4), a, b);
            i += 4;
        }
        //解密 
        double a2[4][4] = {
        23,13,20,5,
        0,10,11,0,
        9,11,15,22,
        9,22,6,25
        };
        string c2;
        i = 0;
        while (i != m.size()) {
            c2 += decypt(m.substr(i, 4), a2, b);
            i += 4;
        }
        //还原空格 
        for (i = pos.size() - 1; i >= 0; --i)c.insert(pos[i], " ");
        for (i = pos.size() - 1; i >= 0; --i)m.insert(pos[i], " ");
        for (i = pos.size() - 1; i >= 0; --i)c2.insert(pos[i], " ");
        cout << c << endl;
        cout << m << endl;
        cout << c2 << endl;
        return 0;
    }
    
    更多相关内容
  • 描述:多表代换密码加密或解密。 参数列表: [strings1] 第一个字符串 [+/-] 运算符 [strings2] 第二个字符串 命令行格式: 多表代换密码.py [strings1] [+/-] [strings2]
  • 多表代换密码(hill密码) 文件列表 crypt.h crypt.cpp 实验原理+函数说明.docx 原本是课程实验,现分享给大家,不足之处望指正。
  • 多表代换密码

    千次阅读 2018-05-08 22:53:00
    多表代换密码中: \[ A=\begin{bmatrix} {3} & {13}&{21}&{9} \\ {15}&{10}&{6}&{25}\\ {10}&{17}&{4}&{8}\\ {1}&{23}&{7}&{2} \end{bmatri...

    以《现代密码学》习题 1.3 为例:

    设多表代换密码中:
    \[ A=\begin{bmatrix} {3} & {13}&{21}&{9} \\ {15}&{10}&{6}&{25}\\ {10}&{17}&{4}&{8}\\ {1}&{23}&{7}&{2} \end{bmatrix} , B=\begin{bmatrix} {1}\\{21}\\{8}\\{17} \end{bmatrix} \]
    加密为:\(C_i≡A{M_i}+\textbf{B}(mod\ 26)\)
    对明文PLEASE SEND ME THE BOOK, MY CREDIT CARD NO IS SIX ONE TWO ONE THREE EIGHT SIX ZERO ONE SIX EIGHT FOUR NINE SEVEN ZERO TWO,
    用解密变换
    \(M_i≡A^{-1}(C_i-\textbf{B})(mod\ 26)\)
    验证你的结果,其中
    \[ A^{-1}=\begin{bmatrix} {26} & {13}&{20}&{5} \\ {0}&{10}&{11}&{0}\\ {9}&{11}&{15}&{22}\\ {9}&{22}&{6}&{25} \end{bmatrix} \]

    • 根据书 1.4.2 ,先将字符串中空格去除,再取 N 位(N 为矩阵 A 的秩)的字串,进行矩阵乘法,最后再把空格加上,输出。
    • 例 1.4.2 的简单验证:
    #include<bits/stdc++.h>
    #define rap(a,b) for(int a=0;a<b;++a)
    using namespace std;
    string encypt(string m,double a[][3],double b[]){
        string ans;
        for (int i=0;i<3;++i){
            int tmp=0;
            for (int j=0;j<3;++j){
                tmp+=a[i][j]*(m[j]-'A');
            }
            tmp+=b[i];tmp%=26;
            ans+=tmp+'A';
        }
        return ans;
    }
    string decypt(string c,double a[][3],double b[]){
        string ans;
        for(int i=0;i<3;++i){
            int tmp=0;
            for(int j=0;j<3;++j){
                tmp+=a[i][j]*(c[j]-'A'-b[j]);
            }
            ans+=tmp%26+'A';
        } 
        return ans;
    }
    int main(){
        double a[3][3]={
                        11,2,19,
                        5,23,25,
                        20,7,17
                    };
        double b[3]={0,0,0};
        string c="YOUR PIN NO IS FOUR ONE TWO SIX";
        //记录空格位置并去空格 
        vector<int>pos;
        int tmp=c.find(' ');
        while(tmp!=-1)  
        {  
           pos.push_back(tmp);
           c.erase(tmp,1);
           tmp=c.find(' ');
        }  
        int i=0;    
        string m;
        while(i!=c.size()){
            m+=encypt(c.substr(i,3),a,b);
            i+=3;
        } 
        double a2[3][3]={
            10,23,7,
            15,9,22,
            5,9,21
        };
        i=0;    
        string c2;
        while(i!=m.size()){
            c2+=decypt(m.substr(i,3),a2,b);
            i+=3;
        } 
        for(i=pos.size()-1;i>=0;--i)c.insert(pos[i]," ");
        for(i=pos.size()-1;i>=0;--i)m.insert(pos[i]," ");
        for(i=pos.size()-1;i>=0;--i)c2.insert(pos[i]," ");
        cout<<c<<endl; 
        cout<<m<<endl;
        cout<<c2<<endl;
        return 0;
    }
    • 运行结果:
      394393-20180508222459026-1904060876.png
    • 仿照例题,很容易得出习题 1.3 的算法实现:
    #include<bits/stdc++.h>
    #define rap(a,b) for(int a=0;a<b;++a)
    using namespace std;
    string encypt(string m,double a[][4],double b[]){
    string ans;
    for (int i=0;i<4;++i){
    int tmp=0;
    for (int j=0;j<4;++j){
    tmp+=a[i][j]*(m[j]-'A');
    }
    tmp+=b[i];
    ans+=tmp%26+'A';
    }
    return ans;
    }
    string decypt(string c,double a[][4],double b[]){
    string ans;
    int cc[4];
    for(int i=0;i<4;++i)cc[i]=(int)(c[i]-'A'-b[i]+26)%26;
    for(int i=0;i<4;++i){
    int tmp=0;
    for(int j=0;j<4;++j){
    tmp+=a[i][j]*cc[j];
    }
    ans+=tmp%26+'A';
    } 
    return ans;
    }
    int main(){
    double a[4][4]={
    3,13,21,9,
    15,10,6,25,
    10,17,4,8,
    1,23,7,2
    };
    double b[4]={1,21,8,17};
    string c="PLEASE SEND ME THE BOOK, MY CREDIT CARD NO IS SIX ONE TWO ONE THREE EIGHT SIX ZERO ONE SIX EIGHT FOUR NINE SEVEN ZERO TWO";
    //记录空格位置并去空格 
    vector<int>pos;
    int tmp=c.find(' ');
    while(tmp!=-1)  
       {  
           pos.push_back(tmp);
           c.erase(tmp,1);
           tmp=c.find(' ');
    }  
    //加密 
    int i=0;
    string m;
    while(i!=c.size()){
    m+=encypt(c.substr(i,4),a,b);
    i+=4;
    } 
    //解密 
    double a2[4][4]={
    26,13,20,5,
    0,10,11,0,
    9,11,15,22,
    9,22,6,25
    };
    string c2;
    i=0;
    while(i!=m.size()){
    c2+=decypt(m.substr(i,4),a2,b);
    i+=4;
    }
    //还原空格 
    for(i=pos.size()-1;i>=0;--i)c.insert(pos[i]," ");
    for(i=pos.size()-1;i>=0;--i)m.insert(pos[i]," ");
    for(i=pos.size()-1;i>=0;--i)c2.insert(pos[i]," ");
    cout<<c<<endl; 
    cout<<m<<endl;
    cout<<c2<<endl;
    return 0;
    }
    • 输出结果:
      394393-20180508222218862-2144550477.png
    • What's?! 居然不对??让我们对前四个字符 "PLEA" 手工验算一下:
      加密过程:
      \[ M=\begin{bmatrix} {3} & {13}&{21}&{9} \\ {15}&{10}&{6}&{25}\\ {10}&{17}&{4}&{8}\\ {1}&{23}&{7}&{2} \end{bmatrix}* \begin{bmatrix} {15}\\ {11}\\ {4}\\ {0} \end{bmatrix}= \begin{bmatrix} {272}\\{359}\\{353}\\{296} \end{bmatrix} +B\begin{bmatrix} {1}\\{21}\\{8}\\{17} \end{bmatrix}= \begin{bmatrix} {273}\\{380}\\{361}\\{313} \end{bmatrix} mod\ 26= \begin{bmatrix} {13}\\{16}\\{23}\\{1} \end{bmatrix} =\begin{bmatrix} {'N'}\\{'Q'}\\{'X'}\\{'B'} \end{bmatrix} \]
      解密过程:
      \[ C=(\begin{bmatrix} {13}\\{16}\\{23}\\{1} \end{bmatrix} -\begin{bmatrix} {1}\\{21}\\{8}\\{17} \end{bmatrix})= \begin{bmatrix} {12}\\{-5}\\{15}\\{-16} \end{bmatrix}* \begin{bmatrix} {26} & {13}&{20}&{5} \\ {0}&{10}&{11}&{0}\\ {9}&{11}&{15}&{22}\\ {9}&{22}&{6}&{25} \end{bmatrix}= \begin{bmatrix} {935}\\{375}\\{784}\\{910} \end{bmatrix}mod\ 26= \begin{bmatrix} {'Z'}\\{'L'}\\{'E'}\\{'A'} \end{bmatrix} \]
      说明算法没有任何问题,那么问题就在问题本身了。
      将给定的 \(A\)\(A^{-1}\) 进行乘法运算:
      \[ A*A^{-1}=\begin{bmatrix} {3} & {13}&{21}&{9} \\ {15}&{10}&{6}&{25}\\ {10}&{17}&{4}&{8}\\ {1}&{23}&{7}&{2} \end{bmatrix}* \begin{bmatrix} {26} & {13}&{20}&{5} \\ {0}&{10}&{11}&{0}\\ {9}&{11}&{15}&{22}\\ {9}&{22}&{6}&{25} \end{bmatrix}= \begin{bmatrix} {348} & {598} & {572}& {702}\\ {669}& {911}& {650}& {832}\\ {368}& {520}& {495}& {338}\\ {107}& {364}& {390}& {209} \end{bmatrix} \]
      而结果矩阵 mod 26 并不是单位矩阵,经过计算,正确的 \(A^{-1}=\)
      \[ \begin{bmatrix} {23} & {13}&{20}&{5} \\ {0}&{10}&{11}&{0}\\ {9}&{11}&{15}&{22}\\ {9}&{22}&{6}&{25} \end{bmatrix} \]
      再次带入程序验证:
      394393-20180508225015850-1195925474.png
    • 感谢现代密码学编者让我浪费的两小时。

      以《现代密码学》习题 1.4 为例:

      首先求出
      \[ C=\begin{bmatrix} {3}\\{14}\\{13}\\{19} \end{bmatrix}, M=\begin{bmatrix} {4}\\{11}\\{13}\\{8} \end{bmatrix} \]

      \[ A=\begin{bmatrix} {a}&{b}\\{c}&{d} \end{bmatrix}有 \begin{bmatrix} {3}\\{14} \end{bmatrix}* \begin{bmatrix} {a}&{b}\\{c}&{d} \end{bmatrix}=\begin{bmatrix} {4}\\{11} \end{bmatrix}, \begin{bmatrix} {13}\\{19} \end{bmatrix}* \begin{bmatrix} {a}&{b}\\{c}&{d} \end{bmatrix}=\begin{bmatrix} {4}\\{11} \end{bmatrix} \]
      可得
      \[ \begin{cases} {3*a+14*b≡4(mod\ 26)} &{①}\\ {3*c+14*d≡11(mod\ 26)}&{②}\\ {13*a+19*b≡13(mod\ 26)}&{③}\\ {13*c+19*d≡8(mod\ 26)}&{④} \end{cases} \]
      下面给出 b 的解法:
      \[ 将①与③联立化简得125b≡13(mod\ 26)\\(5*26-5)b≡13(mod\ 26)\\-5b≡13(mod\ 26)\\-5*5b≡13*5(mod\ 26)\\\\-(26-1)b≡13(mod\ 26)\\b≡13(mod\ 26)\\ 得 b=13。 \]
      同理解得:
      \[ A=\begin{bmatrix} {10}&{13}\\{9}&{23} \end{bmatrix} \]

    转载于:https://www.cnblogs.com/shy-/p/9011396.html

    展开全文
  • 二、实验项目名称:多表代换密码算法实现 三、实验学时:2 学时 四、实验原理: 五、实验目的: 1、熟悉多表代换密码算法; 2、掌握密码算法中参数选取、密钥生成、加密和解密的基本流程。 六、实验内容: 实现n=3...

    一、实验室名称:攻防实验室
    二、实验项目名称:多表代换密码算法实现
    三、实验学时:2 学时
    四、实验原理:
    在这里插入图片描述
    五、实验目的:
    1、熟悉多表代换密码算法;
    2、掌握密码算法中参数选取、密钥生成、加密和解密的基本流程。
    六、实验内容:
    实现n=3的多表代换密码体制,能够随机生成密钥对输入的英文字母信息进行加密或正确解密。
    七、实验器材(设备、元器件):
    学生每人一台PC,安装Windows 7操作系统及VC++/Python开发环境。
    八、实验步骤:
    1.密钥生成
    (1)随机生成3ⅹ3可逆矩阵A,其中在这里插入图片描述
    在这里插入图片描述
    计算其行列式并模去26,若其行列式等于零或与26不互素,则重新生成矩阵。矩阵生成后,计算其在模26下的逆矩阵。
    //产生满足条件的随机三阶矩阵A
    srand(time(0));
    do{
    for(i=0;i<M;i++){
    for(j=0;j<M;j++){
    A[i][j]=rand()%26; } }
    det = -1;
    for(i=1; det < 0; i++){
    det = ((A[0][0]*A[1][1]*A[2][2]+A[1][0]*A[2][1]*A[0][2]+A[0][1]*A[1][2]*A[2][0]-A[0][2]*A[1][1]*A[2][0]-A[0][0]*A[1][2]*A[2][1]-A[0][1]*A[1][0]*A[2][2]) + 26 * i)%26; //行列式的表达式
    }
    }while(gcd(det,26)!=1||det==0); //行列式必须不等于0并且与26互素
    printf(“Encryption matrix A: \n”);
    for(i=0;i<3;i++){
    for(j=0;j<3;j++){
    printf("%d “,A[i][j]); }
    printf(”\n");
    } //输出生成的A矩阵
    这里我和实验二中的Hill2密码一样,密钥的生成采用随机产生符合条件的加密矩阵的形式。随机产生三阶矩阵并模26,计算其行列式的值,三阶行列式的计算公式如图所示。
    在这里插入图片描述
    其中实线相连的三个元素前面的符号是正值,虚线相连的三个元素前面的符号是负值,将相连的符合相乘,再将各组乘得的结果相加并模26,就可以得到三阶行列式的值,若其行列式等于零或与26不互素,则重新生成矩阵。
    //以下为求A的伴随矩阵
    comA[0][0] = (A[1][1] * A[2][2] - A[2][1] * A[1][2]);
    comA[1][0] = -(A[1][0] * A[2][2] - A[1][2] * A[2][0]);
    comA[2][0] = (A[1][0] * A[2][1] - A[1][1] * A[2][0]);
    comA[0][1] = -(A[0][1] * A[2][2] - A[0][2] * A[2][1]);
    comA[1][1] = (A[0][0] * A[2][2] - A[0][2] * A[2][0]);
    comA[2][1] = -(A[0][0] * A[2][1] - A[0][1] * A[2][0]);
    comA[0][2] = (A[0][1] * A[1][2] - A[0][2] * A[1][1]);
    comA[1][2] = -(A[0][0] * A[1][2] - A[0][2] A[1][0]);
    comA[2][2] = (A[0][0] * A[1][1] - A[0][1] * A[1][0]);
    在HILL2加密中,求二阶矩阵的伴随矩阵比较简单,对于三阶及以上矩阵的伴随矩阵,主对角元素是将原矩阵该元素所在行列去掉再求行列式。非主对角元素是原矩阵该元素的共轭位置的元素去掉所在行列求行列式乘以在这里插入图片描述
    ,x和y为该元素的共轭位置的元素的行和列的序号,序号从1开始的。主对角元素实际上是非主对角元素的特殊情况,因为x=y,所以在这里插入图片描述
    ,一直是正数,没必要考虑主对角元素的符号问题。
    i = 1;
    while(1){
    if((det * i) % 26 == 1){
    invdet = i;
    break;}
    else i++;
    } //求三阶矩阵A的行列式的逆元为invdet
    //以下求A的逆矩阵
    for (i = 0; i < 3; i++){
    for (j = 0; j < 3; j++){
    invA[i][j]=invdet
    comA[i][j];
    invA[i][j] %= 26;
    if (invA[i][j] < 0) invA[i][j] += 26;
    }}
    求A的逆使用公式,用A的行列式的逆元为invdet与伴随矩阵相乘。这些计算都是在mod 26的条件下进行。
    (2)生成3维向量在这里插入图片描述
    ,其中在这里插入图片描述
    //以下生成B矩阵
    do{
    for (i = 0; i < 3; i++)
    B[i]=rand()%25;
    }while(B[1]==0&&B[2]==0&&B[0]==0);
    printf(“In this experiment,we use Key B as follows:\n”);
    printf("%d %d %d\n",B[0],B[1],B[2]);
    对于密钥B向量而言,其元素没有什么条件限制,保证其中的每个元素的范围在0-25范围内即可。
    (3)保存A,A-1,B作为秘密密钥。
    2. 加密
    (1)输入一段英文,将其转变成0~25之间的整数,并将这些整数分为3个一组;
    下面就要把输入的英文字母转化为0-25之间的整数,由于输入的明文字符串有大小写之分,所以这里统一将大写字母转化为小写字母进行加密,a-z分别对应0-25。
    for(i=0; i<len; i++){
    if(pla[i] >= ‘A’ && pla[i] <= ‘Z’){
    pla[i] = pla[i] + 32;
    }
    tran1[i] = pla[i] - ‘a’;
    }
    对于在这里插入图片描述
    (2),计算在这里插入图片描述
    这里需要注意数组类型的区分,tran1,s,ciph都是char型的数组,而T1和cip是int型的数组。通过算法得到s数组之后要注意加上97(‘a’)的,由0-25的数值通过加上‘a’得到对应的字母的ascll码值,从而ciph输出相应的密文字母。
    以下是C语言代码实现:
    for(i=0; i<len; i=i+3){
    T1[0] = tran1[i];
    T1[1] = tran1[i + 1];
    T1[2] = tran1[i + 2];
    // cip存储密文int值
    cip[0] = ((A[0][0]*T1[0]+A[0][1]*T1[1]+A[0][2]*T1[2])+B[0]) % 26;
    cip[1] = ((A[1][0]*T1[0]+A[1][1]*T1[1]+A[1][2]*T1[2])+B[1]) % 26;
    cip[2]= ((A[2][0]*T1[0]+A[2][1]*T1[1]+A[2][2]*T1[2])+B[2]) % 26;
    s[i] = cip[0];
    s[i + 1] = cip[1];
    s[i + 2] = cip[2];
    }
    //准备输出解密密文,将这些密文都放入到ciph数组中,此时ciph数组内的元素个数一定是3的倍数
    for(i=0; i<len; i++)
    ciph[i] = s[i] + ‘a’;
    (3)循环加密直到所有的字母都加密完毕。(思考:若输入的英文包含的字母个数不是3的倍数,如何处理?)
    在Hill2加密算法中,由于需要加密的明文是每两个字符成为一组进行加密的,所以我们需要考虑明文字符串中字符的的奇偶个问题。而对于多表代换算法,这些字符是每三个成为一组进行变换,所以我们需要考虑mod 3余0、1、2三种情况,并对于不足三个字符的组进行补齐,这里补上元素‘a’。
    len=strlen(pla)-1; //使用这样方式读写数组最后一个会多出一个空格,我们在操作中需要丢弃这个空格,所以strlen(pla)-1才是实际的长度
    if(len % 3 == 2){ //填充
    pla[len] = ‘a’;
    len = len+1;
    flag = 1;
    }
    if(len % 3 == 1){ //填充
    pla[len] = ‘a’;
    len = len+1;
    pla[len] = ‘a’;
    len = len+1;
    flag = 2;}
    由于加密算法的设计,明文必须每三个一组进行加密,这一组整数要看作为一个整体,在得到密文后,明文与密文并不是一一对应的关系,而是每三个与密文的三个相对应。同一串明文,在末尾补的字母不同会导致得到的密文不同,这里需要注意,不可把明文与密文单个对应。
    (4)保存密文。
    为了方便后续的解密工作,在把密文根据需要输出的同时,我把原密文储存在output.txt文档中。
    3. 解密
    (1)读入密文,将其转变成0~25之间的整数,并将这些整数分为3个一组;
    这里的密文字符个数一定是3的倍数,因为在加密中得到的密文一定是3的倍数并储存咋output.txt中,解密部分读入的密文就来自这个文本文档。所以解密时无需对密文字符串进行长度判断、添加哑字母,直接将其转变成0-25之间的整数,即可以进行解密。
    len=strlen(ciph); //此时的len依旧是3的倍数
    for(i=0; i<len; i++){
    tran2[i] = ciph[i] - ‘a’;
    }
    (2)对于在这里插入图片描述,计算在这里插入图片描述
    解密的过程就是加密的逆过程,只需将加密的步骤逆运算即可。
    // 得到解密后的明文
    for(i=0; i<len; i=i+3){
    T2[0] = tran2[i];
    T2[1] = tran2[i + 1];
    T2[2] = tran2[i + 2];
    x[0]=T2[0]-B[0]; //x矩阵计算C-B的值
    x[1]=T2[1]-B[1];
    x[2]=T2[2]-B[2];
    // msg存储明文int值
    msg[0] = (x[0]*invA[0][0]+x[1]*invA[0][1]+x[2]*invA[0][2]) % 26;
    msg[1] = (x[0]*invA[1][0]+x[1]*invA[1][1]+x[2]*invA[1][2]) % 26;
    msg[2] = (x[0]*invA[2][0]+x[1]*invA[2][1]+x[2]*invA[2][2]) % 26;
    if(msg[0]<0) msg[0]+=26;
    if(msg[1]<0) msg[1]+=26;
    if(msg[2]<0) msg[2]+=26;
    //mes矩阵接受解密后得到的明文的ascll码值
    mes[i] = msg[0];
    mes[i+1]=msg[1];
    mes[i+2]=msg[2];
    }
    (3)循环解密直到所有的字母都解密完毕。
    (4)保存明文并将其与开始加密的明文进行比较,判断是否正确。
    九、实验数据及结果分析:
    (1)实验参考代码:
    请移步资源区
    (2) 加密及解密实例结果截图:
    (1)当明文字符个数为3的倍数余2时:
    待加密的明文plain.txt:
    在这里插入图片描述
    生成随机矩阵进行加密并解密:
    在这里插入图片描述
    (2)当明文字符个数为3的倍数余1时:
    待加密的明文plain.txt:
    在这里插入图片描述
    在这里插入图片描述
    (3)当明文字符个数为3的倍数时:
    待加密的明文plain.txt:
    在这里插入图片描述
    在这里插入图片描述
    十、实验结论:
    实现n=3的多表代换密码体制,并且能够随机生成密钥对输入的英文字母信息(不区分大小写)进行加密或正确解密。
    十一、总结及心得体会:
    多表替代加密算法需要用到很多书论方面的知识。求模整数下的逆矩阵也很有技巧,需要注意每次运算都要模去26。
    多表代换加密及解密算法与Hill2加密解密算法大体思路是一致的,区别在于,Hill2算法是将明文或密文串两两分为一组,使用二阶加密矩阵来进行的加密与解密运算,而多表代换则使用三阶加密矩阵,将明文与密文每三个划为一组,来进行加密与解密算法。多表代换相对Hill2的情况略复杂,因为面对模3余1、2和模3整除的三种情况,来添加哑字母。另外三阶矩阵和三阶行列式的运算也较为复杂。但是两种密码算法的思路大体一致,代码的实现也基本相同。只要理解了Hill2算法,多表代换算法也不难实现。
    另外一个需要注意的地方是,得到加密后的密文时,不应该根据明文中哑字母位对应的密文字符舍掉,因为多表代换中,明文与密文是三三对应的,不能在同一组(3个)明文通过加密得到的一组(3个)密文的情况下,将其中的个别字符的明文与密文单独对应,它们不是一一对应关系。所以我加密得到的密文需要储存在output.txt中,在后续解密时直接从该文本文档中输入。
    十二、对本实验过程及方法、手段的改进建议:
    代码的实现可以写得更简洁明朗一些,逻辑上也应该更加全面。本次实验几乎与Hill2算法的思路和代码一致,其实可以有更多的思考,找到更合适更简洁的方法。

    展开全文
  • 解决一些生活的打加密和解密解决一些生活的打加密和解密
  • 压缩包内有一个C语言代码,实现密码算法的加密解密,还有两个文本文档,是代码实现过程中的输入与输出文档。多表代换与Hill2密码算法类似,这里是3阶的,基于C语言实现 密钥矩阵随机生成、加密、解密
  • java多表代换密码.zip

    2022-02-28 11:10:25
    java多表代换密码.zip
  • 多表代换密码 python

    千次阅读 2018-12-25 16:16:30
          ​ import numpy import math import random def Euclid(a,b=26): x1 = 1 x2 = 0 x3 = a y1 = 0 y2 = 1 y3 = b while y3 != 0 : q = int(x3/y3) ...

     

     

     

     

    ​
    
    import numpy
    import math
    import random
    def Euclid(a,b=26):
        x1 = 1
        x2 = 0
        x3 = a
        y1 = 0
        y2 = 1
        y3 = b
    
        while y3 != 0 :
            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
    
            if x1<0:
                x1 = x1+b
        return x1
    
    def monijuzhen(x,x_value):
        yzs=[]
        x_moni=[[],[],[]]
        for i in range(3):
            for j in range(3):#求9个代数余子式
    
                for m in range(3):
                    for n in range(3):
                        if m!=i and n!=j: #与x[i][j]不在同一行,同一列
                            yzs.append(x[n][m])
                #print('yzs:\n',yzs)
                #此时代数余子时的矩阵已出,即xyz
                yzs_value = ((pow(-1,i+j)*((yzs[0]*yzs[3]-yzs[1]*yzs[2])%26))*Euclid(x_value))%26
                x_moni[i].append(yzs_value)
                yzs=[]
        print('x_moni:\n',x_moni)
        return x_moni
    
    
    def duobiaoencrypt(m,A,B,M_c):
        C=''
        c11=[[],[],[]]
        if M_c==1:
            m=m+chr(random.randint(0,25)+97)+chr(random.randint(0,25)+97)
        elif M_c==2:
            m=m+chr(random.randint(0,25)+97)
    
    
        for i in range(len(m)):    #先假设m是3的倍数
            if  i%3==0:
                c11[0].append(ord(m[i])-97)
            elif i%3==1:
                c11[1].append(ord(m[i])-97)
            elif i%3==2:
                c11[2].append(ord(m[i])-97)
                c11=numpy.mat(c11)
                #print('临时列表c11:\n',c11)
                A=numpy.mat(A)
                #print('en中A:\n',A)
                B=numpy.mat(B)
                #print('en中B:\n',B)
                c11=A*c11
                #print('A*C11:\n',c11)
                c11=c11+B
                #print('c11*A+B:\n',c11)
                c11=c11.tolist()
                #print('最后的c11:\n',c11)
                x=chr((c11[0][0])%26+97)
                y=chr((c11[1][0])%26+97)
                z=chr((c11[2][0])%26+97)
                C=C+x+y+z
                c11=[[],[],[]]
    
        if M_c!=0:
            C_origin=C[:M_c-3]
        else:
            C_origin=C[:]
        print('加密后为',C_origin)
        return C                                    #返回和打印的不同,因为只要B不在[0,0,0],加入不全M的无论是什么都会影响最后一组的结果
    
    
    def duobiaodecrypt(m,A_1,B,M_c):
        C=''
        c11=[[],[],[]]
    
        if M_c==1:
            m=m+chr(random.randint(0,25)+97)+chr(random.randint(0,25)+97)
        elif M_c==2:
            m=m+chr(random.randint(0,25)+97)     #加上a的话asc为97,最后为0不影响结果(只在B为[0,0,0]时才行)
    
    
        for i in range(len(m)):    #先假设m是3的倍数
            if  i%3==0:
              c11[0].append(ord(m[i])-97)
            elif i%3==1:
                c11[1].append(ord(m[i])-97)
            elif i%3==2:
                c11[2].append(ord(m[i])-97)
                c11=numpy.mat(c11)
                A_1=numpy.mat(A_1)
                B=numpy.mat(B)
                #print('de中c11\n',c11)
                #print('de中A_1\n',A_1)
                #print('de中B\n',B)
                temp_c11_B=c11-B
    
                #转化为正数
                temp_c11_B=temp_c11_B.tolist()
                for i in range(3):
                    temp_c11_B[i][0]=temp_c11_B[i][0]%26
                temp_c11_B=numpy.mat(temp_c11_B)
    
                #print('de中c11-B\n',temp_c11_B)
                c11=A_1*temp_c11_B
                #print('de中A_1*(c11-B):\n',c11)
                c11=c11.tolist()
                x=chr((c11[0][0])%26+97)
                y=chr((c11[1][0])%26+97)
                z=chr((c11[2][0])%26+97)
                C=C+x+y+z
                c11=[[],[],[]]
        if M_c!=0:
            C_origin=C[:M_c-3]
        else:
            C_origin=C[:]
        print('解密后为',C_origin)
        return C
    
    #开始
    #随机生成3X3的矩阵A
    
    A = [[],[],[]]
    while (1):
        for i in range(3):
            for j in range(3):
                A[i].append(random.randint(0,25))
        A_value =A[0][0]*(A[1][1]*A[2][2]-A[1][2]*A[2][1])-A[0][1]*(A[1][0]*A[2][2]-A[1][2]*A[2][0])+A[0][2]*(A[1][0]*A[2][1]-A[1][1]*A[2][0])
        A_value = A_value%26
        if (A_value==13 or A_value%2==0 ):
            A = [[],[],[]]
            continue
        else:
            print('A:\n',A)
            print('A_value:\n',A_value)
            break
    
    #矩阵B
    B = [[],[],[]]
    
    for i in range(3):
        B[i].append(random.randint(0,25))
    print('B:\n',B)
    
    
    '''
    A=[[0,7,22],[12,16,9],[5,0,12]]
    B=[[3],[13],[25]]
    A_value =A[0][0]*(A[1][1]*A[2][2]-A[1][2]*A[2][1])-A[0][1]*(A[1][0]*A[2][2]-A[2][0]*A[1][2])+A[0][2]*(A[1][0]*A[2][1]-A[1][1]*A[2][0])
    A_value = A_value%26
    print('A_value:',A_value)
    '''
    #逆矩阵
    A_1=A[:]
    A_1=monijuzhen(A_1,A_value)
    
    M = input('M:')
    #C = input('C:')
    
    M_completion=len(M)%3
    
    C = duobiaoencrypt(M,A,B,M_completion)
    duobiaodecrypt(C,A_1,B,M_completion)
    
    [点击并拖拽以移动]
    ​

     

    展开全文
  • 多表代换密码是以一系列(两个以上)代换表依次明文消息的字母进行代换的加密方法维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。维吉尼亚密码java...
  • 古典密码——vigenre多表代换密码

    千次阅读 2017-09-28 22:50:29
    加密vigenre密码根据包含26张字符对应的vigenre方阵(见文末图)来实现对字符串的加密
  • 介绍:先输入n, 然后输入n * n 矩阵,最后输出矩阵的值。#include &lt;bits/stdc++.h&gt; using namespace std; float result; int A[1010][1010]; float AA[1010][1010]; int n; void Swap(float *a, ...l...
  • 多表代换密码跟单表代换密码的区别,主要是,多表代换的代换表有多个。对于加密,交替使用不同的代换表。注意,加密和解密要同步,也就是,加密和解密所用的代换表顺序要一致,不然,解密会出错。 多表代换跟单表...
  • 分组密码属于多表代换密码还是单表代换密码
  • 密码学】多表代换

    2021-09-07 18:15:48
    解析都在代码里 /* 本版本支持 ASCII码 */ #include <iostream> #include <string> #define N 4 // 定义分组数 using namespace std;...string multiplication(char* str,int a[N][N]);...
  • 描述:单表代换密码加密或解密。 参数列表: encode 加密 decode 解密 [strings] 待加密或解密的密文 [k] 位移值(0为遍历) 命令行格式: 单表代换密码.py encode [strings] [k] 单表代换密码.py...
  • 一、周期置换密码  周期置换密码是将明文字符串P按固定的长度m进行分组,然后对每组字符串中的字符按照某个密钥重新排位的到密文C。其中密钥S包含分组长度信息。解密时只需得到密钥S的逆置换,把密文重新分组,...
  • 自己写的 呵呵 希望支持 信息安全 古典加密算法------置换密码 古典加密算法------代换密码------乘数密码
  • 本文附有丰富的代码,故文章冗长,请对照目录查阅,各大...代换:将明文中的字符替代成其他字符(仿射变换、多表代换)。 在线性空间的变化中,古典加密就是移动并拉伸物体,让物体变得与原来不一样;解密解释将物...
  • 多表代换加密解密(python实现)

    千次阅读 2018-11-17 16:53:43
    多表代换加密解密(python实现):   多表代替密码:由多个简单的代替密码构成,例如,可能有5个被使用的不同的简单代替密码,单独的一个字符用来改变明文的每个字符的位置。其算法可简述为:设密钥为k,明文为m...
  • 多表代换

    千次阅读 2019-04-27 18:49:40
    多表代换密码首先将明文分为由n个字母构成的分组,对每个分组的加密为: 其中(A,B)是密钥,A是n*n的可逆矩阵,满足 对密文分组的解密为: 五、实验目的: 1、熟悉多表代换密码算法; 2、掌握密码算法中参数选取...
  • 多表代换 1 加密过程 由于我没找到与此相关的较为详细的定义,这里我用自己的话简单概括。 我们给定一个n阶方阵A,并给出一段长度为n*m的明文和一个常数字母C,对于每组明文: 将每个明文字母按照a0-z25的顺序...
  • 多表加密算法的java实现,局限于对内容为英文的.txt文件
  • 古典密码加密解密之多表代换

    千次阅读 2017-10-13 16:44:47
    多表代换密码首先将明文M 分为由n 个字母组成的分组, , … ,对每个分组的加密为 ≡ + ( ), = , , … 其中,(A,B)是密钥,A 是 × 的可逆矩阵,满足gcd(|A|,N)=1,( |A|是A 的行列式), = (, , … ), =(, , … ), =...
  • 表代换密码体制

    千次阅读 2021-07-27 20:33:04
    表代换密码体制 所谓代换,是指将明文的字符,用字符集的其他字符代替,从而变成密文。单代换,顾名思义,有一张代换中描述了代换关系。值得注意的是,代换关系可以是一对,但是必须要保证的可逆性,即...
  • C+实现多表代替密码

    2012-06-25 18:24:15
    输入输出 输入: 密钥: hello mingwen.txt的内容: abcdefghijklmnopqrstuvwxyz 输出: 密文.txt的内容: Hfnosmkstxrpxycwucdhbzhimg
  • 置换密码/huanweim 置换密码(Permutation Cipher)又叫换位密码(Transposi-tionCipher),它根据一定的规则重新排列明文,以便打破明文的结构特性。置换密码的特点是保持明文的所有字符不变,只是利用置换打乱了...
  • polyalphabetic-substitution-cipherPolyalphabetic Substitution Cipher:基于仿射变换的多表代换密码的C语言实现多表代换编程实现原理编程语言C编程环境Ubuntu 18.04编译器gcc源代码文件说明polyalphabetic_...
  • 维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。 设d为一固定的正整数,d个位移代换表π=(π1,π2,…,πd),由密钥序列K=(k1,k2,…,kd)给定,第 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,329
精华内容 2,131
关键字:

多表代换密码