1. 程式人生 > >[古典密碼]:Hill cipher(希爾密碼)

[古典密碼]:Hill cipher(希爾密碼)

希爾加密法

根據字典序將字母轉化為數字(0-25)
設定金鑰矩陣(n*n),將明文轉化為r*n的矩陣

將明文矩陣與金鑰矩陣相乘即可得到密文矩陣(結果模26),再將其轉化為字母即可.

以3*3金鑰矩陣為例:(確保金鑰矩陣能求逆)

int key[3][3] = {
	6,13,20,
	24,16,17,
	1,10,15
};

假設明文CAT,C=2,A=0,T=19,明文矩陣:(2,0,19)T

則密文矩陣:

[(6,13,20)T(24,16,17)T(1,10,15)T]×(2,0,19)T

=(31,216,325)T=(5,8,13)T(mod 26)

密文:5=F , 8=I, 13=N :FIN

解密:

將密文矩陣×金鑰矩陣的逆即可

密文:5=F , 8=I, 13=N :FIN

金鑰矩陣的逆:

[(8,21,21)T(5,8,12)T(10,21,8)T]×(5,8,13)T

=(2,0,19)T

即為明文CAT

C++實現(固定矩陣為3*3):

#include#includeusing namespace std;
string f = { "CATCATCAT" };
string alphabet = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
string alphabetl = { "abcdefghijklmnopqrstuvwxyz" };
int key[3][3] = {
    6,13,20,
    24,16,17,
    1,10,15
};
int keyM[3][3] = {
    8,21,21,
    5,8,12,
    10,21,8
};
string reCreateStr(string f) {
    string g;
    for (int i = 0;i < f.size();i++) {
        if ((int)(f[i])>64 && (int)(f[i]) < 91) {
            string t;
            t.resize(1);
            t[0] = f[i];
            g.insert(g.size(),t);
        }
        if ((int)(f[i])>64+32 && (int)(f[i]) < 91+32) {
            string t;
            t.resize(1);
            t[0] = f[i]-32;
            g.insert(g.size(), t);
        }
    }
    g.append("/0");
    cout << g << endl;
    return g;
}
string SplitWord_(string f) {
    string g;
    int count_g = 0;
    int char_c = 0;
    //作簡單分割
    for (int i = 0;i < f.size();) {
        for (int j = 0;j < 2;j++) {
            if ((int)(f[i])>64 && (int)(f[i]) < 91) {
                //g[count_g++] = f[i];
                string t_f;
                t_f.resize(1);
                t_f[0] = f[i];
                g.append(t_f);
                char_c++;
            }
            if (((int)(f[i]) > 96) && ((int)(f[i]) < 123)) {
                //g[count_g++] = (char)((int)f[i] - 32);
                string t_f;
                t_f.resize(1);
                t_f[0] = (char)((int)f[i] - 32);
                g.append(t_f);
                char_c++;
            }
            if (char_c == 2 && i != f.size() && i != f.size() - 1) {
                //g[count_g++] = ' ';
                //g.append(" ");
                char_c = 0;
            }
            i++;
        }
    }
    //cout << g << "e"<0) {
        int matrix[3] = { 0 };
        for (int i = 0;i < 3;i++) {
            if ((int)(f[fc])>64 && (int)(f[fc]) < 91) {
                matrix[i] = (int)f[fc]- 65;
            }
            else {
                matrix[i] = 0;
            }
            fc++;
        }
        c -= 3;
        for (int i = 0;i < 3;i++) {
            int temp = 0;
            for (int j = 0;j < 3;j++) {
                temp += matrix[j] * key[j][i];
            }
            string t;
            t.resize(1);
            t[0]=(char)(temp % 26 + 65);
            g.append(t);
        }
    }
    cout << g << endl;
    return g;
}
void decrypt(string &f) {
    string g;
    int c = f.size();
    int fc = 0;
    while (c>0) {
        int matrix[3] = { 0 };
        for (int i = 0;i < 3;i++) {
            if ((int)(f[fc])>64 && (int)(f[fc]) < 91) {
                matrix[i] = (int)f[fc] - 65;
            }
            else {
                matrix[i] = 0;
            }
            fc++;
        }
        c -= 3;
        for (int i = 0;i < 3;i++) {
            int temp = 0;
            for (int j = 0;j < 3;j++) {
                temp += matrix[j] * keyM[j][i];
            }
            string t;
            t.resize(1);
            t[0] = (char)(temp % 26 + 65);

            g.append(t);
        }
    }
    cout << g << endl;
}
int main() {
    f = { "Things are not always what they see" };
    decrypt(encrypt(reCreateStr(f)));
    return 0;
}