Hill密码的基本思想是利用了域Z[26]的线性变换把n个连续的文字字母替换为n个密文字母。其实质是将长消息分组,分组长度由矩阵的维数决定。此密码能更好地抵抗统计分析法,对抗惟密文攻击的强度较高,但易受已知明文攻击。
(C表示密,P表示明文,K表示密钥)
加密函数如下:
解密函数如下:
为求得矩阵的逆,应该先求出该矩阵的伴随矩阵和该矩阵的值。
1. 矩阵的值
int getMatricesValue(int[][] data) {
// 求矩阵的值
int Datasum = 0;
for (int i = 0; i < data[0].length; i++) {
int Datasum1 = 1;
int Datasum2 = 1;// 矩阵的值
int x1 = i;
int y1 = 0;
while (y1 < data.length) {
Datasum1 = Datasum1 * data[y1][x1];
x1++;
y1++;
if (x1 == data[0].length) {
x1 = 0;
}
}
int x2 = i;
int y2 = 0;
while (y2 < data.length) {
Datasum2 = Datasum2 * data[y2][x2];
x2--;
y2++;
if (x2 == -1) {
x2 = data[0].length - 1;
}
}
Datasum = Datasum + (Datasum1 - Datasum2);
}
return Datasum;
}
2.求矩阵对应元素的代数余子式
int getConfactor(int[][] data, int h, int v) {// 求数组坐标为(h,v)的代数余子式
int a = data.length;
int b = data[0].length;
int newdata[][] = new int[a - 1][b - 1];
// 构造新的矩阵
int[] cook = new int[(a - 1) * (b - 1)];
int x = 0;
for (int j = 0; j < data.length; j++)
for (int i = 0; i < data[0].length; i++) {
if (j == v) {
break;
}
if (i == h) {
continue;
}
if (i != h || j != v) {
cook[x] = data[j][i];
x++;
}
}
int y = 0;
for (int j = 0; j < newdata.length; j++) {
for (int i = 0; i < newdata[0].length && y < cook.length; i++ , y++) {
newdata[j][i] = cook[y];
}
}
// 求新矩阵的值,即为对应代数余子式
return getMatricesValue(newdata);
}
3.求伴随矩阵
int[][] getComplex(int data[][]) { // 求伴随矩阵
int[][] newdata = new int[data[0].length][data.length];
for (int j = 0; j < data.length; j++) {
for (int i = 0; i < data[0].length; i++) {
if ((i + j) % 2 == 0) {
newdata[j][i] = getConfactor(data, i, j);
} else
newdata[j][i] = 0 - getConfactor(data, i, j);
}
}
return newdata;
}
4.求该矩阵的逆矩阵
int[][] getInverse(int data[][]) { // 求逆矩阵
int[][] dataInverse = new int[data[0].length][data.length];
int[][] dataComplex = getComplex(data);
int dataValue = getMatricesValue(data);
for (int j = 0; j < dataComplex.length; j++) {
for (int i = 0; i < dataComplex[0].length; i++) {
dataInverse[i][j] = dataComplex[i][j] / dataValue;
}
}
return dataInverse;
}
5.求char类型的一维矩阵与int类型多维矩阵相乘
char[] MulMatrices(char data1[], int data2[][]) {
int[] data = new int[data1.length]; // 存储转为int类型后的明文
char[] newdata = new char[data1.length];
for (int i = 0; i < data2[0].length; i++) { // data2列
int x = 0;
for (int j = 0; x < data2.length && j < data1.length; j++, x++) { // data1列与data2行的元素对应相乘
data[i] = data[i] + ((int) data1[x]) * data2[i][j];
}
}
for (int i = 0; i < newdata.length; i++) {
newdata[i] = (char) (data[i] % 26);
}
return newdata;
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。