码迷,mamicode.com
首页 > 其他好文 > 详细

4 多表代替密码之Hill 密码_1 矩阵工具类

时间:2015-10-09 21:20:02      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

在说明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:

  1 package com.owner.util.matrix;
  2 
  3 import Jama.Matrix;
  4 
  5 import java.text.NumberFormat;
  6 
  7 /**
  8  * Created by wellmax on 2015/10/8.
  9  */
 10 public class MatrixUtil {
 11     private Matrix matrix;
 12 
 13     public MatrixUtil(Matrix matrix) {
 14         this.matrix = matrix;
 15     }
 16 
 17     public MatrixUtil() {
 18     }
 19 
 20     public int dimension(){
 21         return this.getMatrix().getArray().length;
 22     }
 23     private int mod(int number){
 24         int mod = number%26;
 25         return mod < 0 ? mod + 26 : mod;//+26 避免取模结果为负
 26     }
 27     private int convertDouble2Int(Double d){
 28         return d.intValue();
 29     }
 30 
 31     /**
 32      * 计算构成Dji 矩阵的子矩阵矩阵
 33      */
 34     private Matrix excludeRowAndColumn(int row, int column){
 35         double[][] subArr = new double[dimension() - 1][dimension() - 1];
 36         double[][] arr = this.getMatrix().getArray();
 37         int rowFlag = 0;
 38         int columnFlag = 0;
 39         for(int i = 0 ; i < arr.length ; i++){
 40             if(i == row){
 41                 continue;
 42             }
 43             for(int j = 0 ; j < arr.length ; j++){
 44                 if(j == column){
 45                     continue;
 46                 }
 47                 subArr[rowFlag][columnFlag] = arr[i][j];
 48                 columnFlag++;
 49             }
 50             rowFlag++;
 51             columnFlag = 0;
 52         }
 53         return new Matrix(subArr);
 54     }
 55 
 56     /**
 57      * 计算行列式
 58      */
 59     public int determinant(Matrix matrix){
 60         double doubleDeterminant = matrix.det();
 61         return this.mod(this.convertDouble2Int(doubleDeterminant));
 62     }
 63 
 64     /**
 65      * 计算行列式的逆,这个方法有点坑。。。
 66      */
 67     public int negativeDeterminant(int determinant){
 68         int i = 1;
 69         while(true){
 70             if((determinant * i) % 26 == 1){
 71                 return i;
 72             }
 73             if (i == Integer.MAX_VALUE >> 1){
 74                 break;
 75             }
 76             i++;
 77         }
 78         throw new RuntimeException("Could not find the negative determinant");
 79     }
 80 
 81     /**
 82      * 计算D矩阵
 83      */
 84     public Matrix getD(){
 85         double[][] arr = this.getMatrix().getArray();
 86         if (arr == null || arr.length == 0){
 87             return null;
 88         }
 89         double[][] arrD = new double[arr.length][arr.length];
 90         for(int i = 0 ; i < arr.length ; i++){
 91             for(int j = 0 ; j < arr[i].length ; j ++){
 92                 arrD[i][j] = this.determinant(this.excludeRowAndColumn(j,i));
 93             }
 94         }
 95         return new Matrix(arrD);
 96     }
 97 
 98     /**
 99      * 计算(-1)i+j 乘上 D矩阵
100      */
101     public Matrix negative(Matrix matrix){
102         double[][] arr = matrix.getArray();
103         for (int i = 0 ; i < arr.length ; i ++){
104             for(int j = 0 ; j < arr.length ; j++){
105                 if((i+j) % 2 == 1){
106                     arr[i][j] = mod(-1 * new Double(arr[i][j]).intValue());
107                 }
108             }
109         }
110         return new Matrix(arr);
111     }
112 
113     /**
114      * 最后一个求矩阵的逆矩阵
115      */
116     public Matrix inverse(){
117         int negativeDeterminant = negativeDeterminant(determinant(this.getMatrix()));
118         Matrix D = this.negative(this.getD());
119         double[][] arr = D.getArray();
120         double[][] inverseArr = new double[arr.length][arr.length];
121         for(int i = 0 ; i < arr.length ; i++){
122             for (int j = 0 ; j < arr.length ; j++){
123                 inverseArr[i][j] = mod(new Double(arr[i][j]).intValue() * negativeDeterminant);
124             }
125         }
126         return new Matrix(inverseArr);
127     }
128 
129     public Matrix getMatrix() {
130         return matrix;
131     }
132 
133     public void setMatrix(Matrix matrix) {
134         this.matrix = matrix;
135     }
136     public static void main(String[] args){
137         double[][] arr = new double[][]{{5,8},{17,3}};
138         Matrix m = new Matrix(arr,2,2);
139         MatrixUtil util = new MatrixUtil(new Matrix(arr));
140 //        System.out.println(util.determinant());
141         Matrix D = util.getD();
142 //        m.print(NumberFormat.getInstance(),3);
143 //        util.negative(D).print(NumberFormat.getInstance(), 3);
144         util.inverse().print(NumberFormat.getInstance(), 3);
145 
146 
147 //        double[][] det = new double[][]{{9}};
148 //        Matrix detMatrix = new Matrix(det);
149 //        detMatrix.inverse().print(NumberFormat.getInstance(),3);
150     }
151 }

 

 

-wellmaxwang

 

4 多表代替密码之Hill 密码_1 矩阵工具类

标签:

原文地址:http://www.cnblogs.com/wellmaxwang/p/MatrixUtil.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!