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

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

时间: 2024-08-08 01:39:48

4 多表代替密码之Hill 密码_1 矩阵工具类的相关文章

4 多表代替密码之Hill 密码 2实现

该解密方法的KEY 不是一个数或者一段字符串,而是一个矩阵, 比如有个3*3的KEY: 那么如果我们要加密一个长度为N的字符串, 那么把N除以3,分成M个3个字母组成的小段, 对每个小段尽心加密: 1. 将明文分成M个小段:{{p1,p2,p3},{p4,p5,p6}...{..pN}} 2. 对每个小段尽心加密: c1 = (k11*p1 + k21*p2 + k31*p3) c2= (k12*p1 + k22*p2 + k32*p3) c3= (k13*p1 + k23*p2 + k33*p

javascript实现playfair和hill密码算法

时至期末,补习信息安全概论作业.恰巧遇古典密码学算法中的playfair算法和hill算法,用javascript语言实现起来是在有趣,边查百度边编码,顺便好好补习一下javascript基础. playfair Playfair密码(英文:Playfair cipher 或 Playfair square)是一种替换密码.依据一个5*5的正方形组成的密码表来编写,表中排列有25个字母.对于英语中的26个字母,去掉最常用的Z,构成密码表. 实现思路: 1,编制密码表 密钥是一个单词或词组,密码表

古典密码(Hill加密算法)

"Hill的加密与解密" Hill加密是另一种多字母代替密码,与多表代替密码不同的是,Hill密码要求将明文分成同等规模的若干个分组(最后一个分组涉及到填充),每一个分组被整体的加密代换,即希尔密码属于分组加密.Hill密码的算法思想是:将一个分组中的d个连续的明文字母通过线性变换转换为d个密文字母.这种变换由d个线性方程决定,其中每个字母被分配一个数值(0,1,...,25).解密只需要做一次逆变换就可以了,密钥就是变换矩阵本身. 设明文为一维矩阵m,密文为一维矩阵c,密钥用k矩阵表

信息安全-2:python之hill密码算法[原创]

转发注明出处:http://www.cnblogs.com/0zcl/p/6106513.html 前言: hill密码算法我打算简要介绍就好,加密矩阵我用教材上的3*3矩阵,只做了加密,解密没有做,不过我觉得会加密就会解密的~~       一.hill算法原理 hill密码是一种多字母替代密码,由数学学Leste Hill于1929年研制成功.该密码算法取m个连续的明文字母,并用m个密文字母代替,用向量或矩阵表示为(这里取m=3,C和P是长度为3的列向量,K是3*3矩阵): 即:C=KP  

Hill密码

希尔密码(Hill Password)是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明.每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果MOD26.注意用作加密的矩阵(即密匙)在\mathbb_^n必须是可逆的,否则就不可能译码.只有矩阵的行列式和26互质,才是可逆的 #include<stdio.h> #include<string.h> #include<ctype.h&

[WPF]实现密码框的密码绑定

正如绑定TextBox控件的Text属性一样, 我们希望能够将PasswordBox空间的Password属性进行绑定, 比如在MVVM模式中,这似乎是必须的, 但可惜的是, Password属性是不支持绑定的(不是依赖属性, 也没有实现INotifyPropertyChanged). 这可能是出于安全性的考虑. 但在我们的系统为了实现View层密码框中的密码与后台其它层之间的密码属性之间的绑定, 可以采取如下思路: 将密码框的密码和某一个缓冲区进行同步, 缓冲区在和后台进行绑定. 其中密码框与

百万年薪python之路 -- MySQL数据库之 永久修改字符串编码 与 忘了密码和修改密码

永久修改字符集编码的方法: 在mysql安装目录下创建一个my.ini(Windows下)文件,写入下面的配置,然后重启服务端. [client] #设置mysql客户端默认字符集 default-character-set=utf8 [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 user = 'root' password = '123' [mysqld] #设置3306端口 port = 3306 # 设置mysql的安装目录 ba

Linux中Root用户密码变更、密码忘记

用户设置bash的时候,错把root的bash改为bin/bash,注意,不是“/bin/bash”!. 然后就登录不了root了,也修改不了/etc/passwd了. 解决: 1.重启Ubuntu,随即长按shift进入grub菜单: 2.选择recovery mode,即Ubuntu,With Linux 3.2.0-23-generic(recovery mode),按e,编辑启动参数: 3.把ro recovery nomodeset 改成rw single init=/bin/bash

判断密码与确认密码是否一致

已下言论若有问题,希望大家及时提醒.谢谢啦~ 今天写的是注册页面,遇到了很多的问题,下面我把我的问题写出来,希望对大家有一丢丢的帮助,也是我对自己的总结. 首先的问题是若输入正确当失去焦点时输入框后面的'*'变为'√',我一开始用innerHTML来获取'*',但是始终获取不到,后来用val(),ok,终于获取到了.接下来就是在允许的范围内,将'*'变为'√',我用的是html('√'),我试了一下val('√')不可以下面是源码和图示. function checkUser (star,inp