原理:
Hill密码的加解密钥是矩阵,所以会涉及到矩阵求逆和矩阵乘法的运算。
2x2矩阵的求逆
假设我们有一个2x2的矩阵A=,要找到他的逆矩阵我们需要进行以下的步骤:
求矩阵的行列式def(A)
def(A)=ad-bc
//计算2x2行列式的def
int determinantInverse(const Matrix2x2& mat) {
int det = (mat.a * mat.d - mat.b * mat.c) % M;
if (det < 0) det += M;
return modInverse(det, M);
}
求矩阵的行列式的逆元
def(A)xXmod26==1→
//求def的逆元 原来是求逆元,我一直以为是求倒数orz
int modInverse(int a, int m) {
a = a % m;
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) return x;
}
return 1;
}
运用公式求逆矩阵
逆矩阵公式是:
//计算2x2行列式的def
int determinantInverse(const Matrix2x2& mat) {
int det = (mat.a * mat.d - mat.b * mat.c) % M;
if (det < 0) det += M;
return modInverse(det, M);
}
矩阵的乘法
我们这里用的二阶的密钥矩阵,所以将加密文本两个两个的加密。
//加密或解密一个字符对
pair<char, char> encryptDecryptPair(const Matrix2x2& mat, char x1, char x2) {
int y1 = (mat.a * (x1 - 'A') + mat.b * (x2 - 'A')) % M;
int y2 = (mat.c * (x1 - 'A') + mat.d * (x2 - 'A')) % M;
if (y1 < 0) y1 += M;
if (y2 < 0) y2 += M;
return {static_cast<char>(y1 + 'A'), static_cast<char>(y2 + 'A')};
}
//加密或解密文本
string encryptDecrypt(const Matrix2x2& mat, const string& text) {
string result;
for (size_t i = 0; i < text.size(); i += 2) {
pair<char, char> pair = encryptDecryptPair(mat, text[i], text[i + 1]);
result.push_back(pair.first);
result.push_back(pair.second);
}
return result;
}
算法:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int M = 26; // 模数,对应英文字母的数量
//2x2密钥矩阵
struct Matrix2x2 {
int a, b, c, d;
};
//求def的逆元 原来是求逆元,我一直以为是求倒数orz
int modInverse(int a, int m) {
a = a % m;
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) return x;
}
return 1;
}
//计算2x2行列式的def
int determinantInverse(const Matrix2x2& mat) {
int det = (mat.a * mat.d - mat.b * mat.c) % M;
if (det < 0) det += M;
return modInverse(det, M);
}
//求2x2密钥矩阵的逆矩阵
Matrix2x2 inverse(const Matrix2x2& mat) {
int det_inv = determinantInverse(mat);
return {
det_inv * mat.d % M, -det_inv * mat.b % M,
-det_inv * mat.c % M, det_inv * mat.a % M
};
}
//加密或解密一个字符对
pair<char, char> encryptDecryptPair(const Matrix2x2& mat, char x1, char x2) {
int y1 = (mat.a * (x1 - 'A') + mat.b * (x2 - 'A')) % M;
int y2 = (mat.c * (x1 - 'A') + mat.d * (x2 - 'A')) % M;
if (y1 < 0) y1 += M;
if (y2 < 0) y2 += M;
return {static_cast<char>(y1 + 'A'), static_cast<char>(y2 + 'A')};
}
//加密或解密文本
string encryptDecrypt(const Matrix2x2& mat, const string& text) {
string result;
for (size_t i = 0; i < text.size(); i += 2) {
pair<char, char> pair = encryptDecryptPair(mat, text[i], text[i + 1]);
result.push_back(pair.first);
result.push_back(pair.second);
}
return result;
}
int main() {
Matrix2x2 key = {3, 3, 2, 5};//密钥 矩阵
Matrix2x2 keyInverse = inverse(key);//密钥矩阵的逆矩阵
string plaintext = "HELPME";//定义明文
string encrypted = encryptDecrypt(key, plaintext);//加密
string decrypted = encryptDecrypt(keyInverse, encrypted);//解密
cout << "Plaintext: " << plaintext << std::endl;
cout << "Encrypted: " << encrypted << std::endl;
cout << "Decrypted: " << decrypted << std::endl;
return 0;
}