4 多表代替密码之Hill 密码_1 矩阵工具类
2015-10-09 21:03
369 查看
在说明Hill加密之前要先复习线性代数的知识,主要是关于矩阵的一些运算和概念。
一、矩阵的逆:
定义方阵M的逆矩阵应该满足M*M^-1==I,其中I是单位矩阵,比如:
但是这个地方是对英文字母进行加密,所以矩阵中的数字都是模26的值,比如:
*
=
这个地方结果就应该mod26, 最后结果就是:
那么上面两个相乘的矩阵就互为逆矩阵。
这个地方要多说一下密码学中的mod运算,数学中-5%26结果肯定是-5,但是这个地方我们取值只能在0-25之间,所以-5%26的结果应该是21。
求解一个方阵的逆矩阵的公式是: (det A)-1*(-1)i+j(Dji),其中:
1.det A 是矩阵A 的行列式,当然最后结果也要是mod26,(det A)-1的意思是取矩阵A的行列式的逆,比如:
的行列式是5*3-8*17=-121mod26=9
那么(det A)-1 = 3,因为3*8mod26=1,符合矩阵逆的定义。
2.Dji 是将A去掉第j行和dii行的子行列式的值,比如:
是个2*2的方阵,那么i和j就有4种组合:0,0:0,1:1,0:1,1, 那么分别去掉对应的列和行后,就成了4个1*1的方阵,再分别计算这四个方阵的行列式,结果就是:
Dji =
3. (-1)i+j
这个与Dji相乘的结果就是:
mod26 =
最后得到A的逆矩阵为:
mod26=
二、Java中关于矩阵计算的工具包
其中最常用的就是jama了, http://math.nist.gov/javanumerics/jama/
但是要用到我们这个对应26个英文字母的加密算法中还需要进行改造,‘主要是以下几点:
1. jama是针对double类型的,要切换到int或者short
2. jama结果不会取模, 比如手动实现取模
三、我的实现
还是直接来个工具类吧,使用jama:
-wellmaxwang
一、矩阵的逆:
定义方阵M的逆矩阵应该满足M*M^-1==I,其中I是单位矩阵,比如:
但是这个地方是对英文字母进行加密,所以矩阵中的数字都是模26的值,比如:
*
=
这个地方结果就应该mod26, 最后结果就是:
那么上面两个相乘的矩阵就互为逆矩阵。
这个地方要多说一下密码学中的mod运算,数学中-5%26结果肯定是-5,但是这个地方我们取值只能在0-25之间,所以-5%26的结果应该是21。
求解一个方阵的逆矩阵的公式是: (det A)-1*(-1)i+j(Dji),其中:
1.det A 是矩阵A 的行列式,当然最后结果也要是mod26,(det A)-1的意思是取矩阵A的行列式的逆,比如:
的行列式是5*3-8*17=-121mod26=9
那么(det A)-1 = 3,因为3*8mod26=1,符合矩阵逆的定义。
2.Dji 是将A去掉第j行和dii行的子行列式的值,比如:
是个2*2的方阵,那么i和j就有4种组合:0,0:0,1:1,0:1,1, 那么分别去掉对应的列和行后,就成了4个1*1的方阵,再分别计算这四个方阵的行列式,结果就是:
Dji =
3. (-1)i+j
这个与Dji相乘的结果就是:
mod26 =
最后得到A的逆矩阵为:
mod26=
二、Java中关于矩阵计算的工具包
其中最常用的就是jama了, http://math.nist.gov/javanumerics/jama/
但是要用到我们这个对应26个英文字母的加密算法中还需要进行改造,‘主要是以下几点:
1. jama是针对double类型的,要切换到int或者short
2. jama结果不会取模, 比如手动实现取模
三、我的实现
还是直接来个工具类吧,使用jama:
package com.owner.util.matrix; import Jama.Matrix; import java.text.NumberFormat; /** * Created by wellmax on 2015/10/8. */ public class MatrixUtil { private Matrix matrix; public MatrixUtil(Matrix matrix) { this.matrix = matrix; } public MatrixUtil() { } public int dimension() { return this.getMatrix().getArray().length; } private int mod(int number) { int mod = number % 26; return mod < 0 ? mod + 26 : mod;//+26 避免取模结果为负 } private int convertDouble2Int(Double d) { return d.intValue(); } /** * 计算构成Dji 矩阵的子矩阵矩阵 */ private Matrix excludeRowAndColumn(int row, int column) { double[][] subArr = new double[dimension() - 1][dimension() - 1]; double[][] arr = this.getMatrix().getArray(); int rowFlag = 0; int columnFlag = 0; for (int i = 0; i < arr.length; i++) { if (i == row) { continue; } for (int j = 0; j < arr.length; j++) { if (j == column) { continue; } subArr[rowFlag][columnFlag] = arr[i][j]; columnFlag++; } rowFlag++; columnFlag = 0; } return new Matrix(subArr); } /** * 计算行列式 */ public int determinant(Matrix matrix) { double doubleDeterminant = matrix.det(); return this.mod(this.convertDouble2Int(doubleDeterminant)); } /** * 计算行列式的逆,这个方法有点坑。。。 */ public int negativeDeterminant(int determinant) { int i = 1; while (true) { if ((determinant * i) % 26 == 1) { return i; } if (i == Integer.MAX_VALUE >> 1) { break; } i++; } throw new RuntimeException("Could not find the negative determinant"); } /** * 计算D矩阵 */ public Matrix getD() { double[][] arr = this.getMatrix().getArray(); if (arr == null || arr.length == 0) { return null; } double[][] arrD = new double[arr.length][arr.length]; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { arrD[i][j] = this.determinant(this.excludeRowAndColumn(j, i)); } } return new Matrix(arrD); } /** * 计算(-1)i+j 乘上 D矩阵 */ public Matrix negative(Matrix matrix) { double[][] arr = matrix.getArray(); for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { if ((i + j) % 2 == 1) { arr[i][j] = mod(-1 * new Double(arr[i][j]).intValue()); } } } return new Matrix(arr); } /** * 最后一个求矩阵的逆矩阵 */ public Matrix inverse() { int negativeDeterminant = negativeDeterminant(determinant(this.getMatrix())); Matrix D = this.negative(this.getD()); double[][] arr = D.getArray(); double[][] inverseArr = new double[arr.length][arr.length]; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length; j++) { inverseArr[i][j] = mod(new Double(arr[i][j]).intValue() * negativeDeterminant); } } return new Matrix(inverseArr); } private int rowMultiplyEqualLengthMatrix(int[] row, double[] matrix) { double result = 0; for (int i = 0; i < row.length; i++) { result += row[i] * matrix[i]; } return this.mod(this.convertDouble2Int(result)); } public int[] rowMultiplyMatrix(int[] row, Matrix matrix) { int length = row.length; int matrixDimension = matrix.getColumnDimension(); int mod = length % matrixDimension; int cycleTime = length / matrixDimension; int[] result = new int[length]; double[] matrixArr = matrix.getColumnPackedCopy(); int element = 0; double[] cycleMatrixArr = new double[matrixDimension]; int[] cycleRowArr = new int[matrixDimension]; for (int i = 0; i < cycleTime; i++) { System.arraycopy(row, i * matrixDimension, cycleRowArr, 0, matrixDimension); for (int j = 0; j < matrixDimension; j++) { System.arraycopy(matrixArr, j * matrixDimension, cycleMatrixArr, 0, matrixDimension); element = this.rowMultiplyEqualLengthMatrix(cycleRowArr, cycleMatrixArr); result[i * matrixDimension + j] = element; } } if (mod != 0) { for(int i = 0 ; i < matrixDimension ; i ++){ cycleMatrixArr[i] = 0; } System.arraycopy(row, cycleTime * matrixDimension, cycleRowArr, 0, length - cycleTime * matrixDimension); for (int j = 0; j < length - cycleTime * matrixDimension; j++) { System.arraycopy(matrixArr, j * matrixDimension, cycleMatrixArr, 0, matrixDimension); element = this.rowMultiplyEqualLengthMatrix(cycleRowArr, cycleMatrixArr); result[cycleTime * matrixDimension + j] = element; } } return result; } public Matrix getMatrix() { return matrix; } public void setMatrix(Matrix matrix) { this.matrix = matrix; } public static void main(String[] args) { double[][] arr = new double[][]{{5, 8}, {17, 3}}; Matrix m = new Matrix(arr, 2, 2); MatrixUtil util = new MatrixUtil(new Matrix(arr)); // System.out.println(util.determinant()); Matrix D = util.getD(); // m.print(NumberFormat.getInstance(),3); // util.negative(D).print(NumberFormat.getInstance(), 3); util.inverse().print(NumberFormat.getInstance(), 3); int[] row = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; int[] result = util.rowMultiplyMatrix(row, m); for (int i : result) { System.out.println(i); } // double[][] det = new double[][]{{9}}; // Matrix detMatrix = new Matrix(det); // detMatrix.inverse().print(NumberFormat.getInstance(),3); } }
-wellmaxwang
相关文章推荐
- 《代码阅读方法与实践之读书笔记之一》
- 基础篇:操作系统、计算机网络、设计模式(一)(附参考答案)
- POJ 2456 Aggressive cows 二分
- Android 布局技巧
- POJ 1780 【手工递归】【欧拉回路】
- C# 使用MEF动态加载不同的userControl,并实现不同userControl之间通信
- EM2040D和SES2000采集图像判读(一)
- Dinic模板
- android模仿58筛选下拉框(PopupWindow实现)
- 字符流-->字节流
- Codeforces Round #317 (Div. 2) 571A. Lengthening Sticks 组合数学
- 【转】二叉树的三种遍历的相互转化——已知先序中序求后序
- android模仿58筛选下拉框(PopupWindow实现)
- 四元数和旋转矩阵
- Codeforces Round #317 (Div. 2) 572B. Order Book 排序+贪心
- java枚举
- maven3创建多模块web项目
- 生成窗口最大值数组
- Servlet读取头信息
- 基本属性与特殊属性