用Java实现Hill密码加解密
时间: 2023-11-18 12:05:34 浏览: 55
Hill密码是一种基于矩阵乘法的密码算法,它可以用于加密和解密任意长度的文本,同时也可以抵御一定程度的密码分析攻击。下面是用Java实现Hill密码加解密的示例代码:
```
import java.util.Scanner;
public class HillCipher {
// 矩阵加法
public static int[][] matrixAdd(int[][] A, int[][] B) {
int[][] C = new int[A.length][A[0].length];
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[0].length; j++) {
C[i][j] = A[i][j] + B[i][j];
}
}
return C;
}
// 矩阵乘法
public static int[][] matrixMul(int[][] A, int[][] B) {
int[][] C = new int[A.length][B[0].length];
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B[0].length; j++) {
for (int k = 0; k < B.length; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
return C;
}
// 矩阵求逆
public static int[][] matrixInverse(int[][] A) {
int n = A.length;
int[][] B = new int[n][n];
int[][] C = new int[n][2 * n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
B[i][j] = A[i][j];
}
C[i][i] = 1;
}
for (int k = 0; k < n; k++) {
int maxRow = k;
for (int i = k + 1; i < n; i++) {
if (Math.abs(B[i][k]) > Math.abs(B[maxRow][k])) {
maxRow = i;
}
}
if (maxRow != k) {
int[] tmp = B[k];
B[k] = B[maxRow];
B[maxRow] = tmp;
tmp = C[k];
C[k] = C[maxRow];
C[maxRow] = tmp;
}
if (B[k][k] == 0) {
throw new RuntimeException("Matrix is singular.");
}
int inv = 1 / B[k][k];
for (int j = 0; j < n; j++) {
B[k][j] *= inv;
C[k][j] *= inv;
}
for (int i = 0; i < n; i++) {
if (i != k) {
int f = B[i][k];
for (int j = 0; j < n; j++) {
B[i][j] -= f * B[k][j];
C[i][j] -= f * C[k][j];
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = n; j < 2 * n; j++) {
C[i][j] /= B[i][i];
}
}
int[][] D = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
D[i][j] = C[i][j + n];
}
}
return D;
}
// 加密函数
public static String encrypt(String plaintext, int[][] key) {
int n = key.length;
int m = (plaintext.length() + n - 1) / n * n;
int[][] P = new int[m / n][n];
int k = 0;
for (int i = 0; i < m / n; i++) {
for (int j = 0; j < n; j++) {
if (k < plaintext.length()) {
P[i][j] = plaintext.charAt(k) - 'a';
k++;
} else {
P[i][j] = 0;
}
}
}
int[][] C = new int[m / n][n];
for (int i = 0; i < m / n; i++) {
int[][] Pi = new int[1][n];
for (int j = 0; j < n; j++) {
Pi[0][j] = P[i][j];
}
int[][] Ci = matrixMul(Pi, key);
for (int j = 0; j < n; j++) {
C[i][j] = Ci[0][j];
}
}
StringBuilder ciphertext = new StringBuilder();
for (int i = 0; i < m / n; i++) {
for (int j = 0; j < n; j++) {
ciphertext.append((char) (C[i][j] % 26 + 'a'));
}
}
return ciphertext.toString();
}
// 解密函数
public static String decrypt(String ciphertext, int[][] key) {
int n = key.length;
int m = ciphertext.length();
int[][] C = new int[m / n][n];
int k = 0;
for (int i = 0; i < m / n; i++) {
for (int j = 0; j < n; j++) {
C[i][j] = ciphertext.charAt(k) - 'a';
k++;
}
}
int[][] keyInv = matrixInverse(key);
int[][] P = new int[m / n][n];
for (int i = 0; i < m / n; i++) {
int[][] Ci = new int[1][n];
for (int j = 0; j < n; j++) {
Ci[0][j] = C[i][j];
}
int[][] Pi = matrixMul(Ci, keyInv);
for (int j = 0; j < n; j++) {
P[i][j] = Pi[0][j];
}
}
StringBuilder plaintext = new StringBuilder();
for (int i = 0; i < m / n; i++) {
for (int j = 0; j < n; j++) {
plaintext.append((char) (P[i][j] % 26 + 'a'));
}
}
return plaintext.toString();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入明文:");
String plaintext = sc.nextLine();
System.out.print("请输入密钥:");
int[][] key = new int[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
key[i][j] = sc.nextInt();
}
}
String ciphertext = encrypt(plaintext, key);
System.out.println("密文为:" + ciphertext);
String decryptedText = decrypt(ciphertext, key);
System.out.println("解密后明文为:" + decryptedText);
}
}
```
上面的代码中,我们定义了`matrixAdd`、`matrixMul`和`matrixInverse`三个函数来实现矩阵加法、矩阵乘法和矩阵求逆操作。然后,我们定义了`encrypt`和`decrypt`两个函数来实现加密和解密操作。最后,在`main`函数中,我们通过键盘输入明文和密钥,然后输出加密后的密文和解密后的明文。