您的位置:首页 > 编程语言 > Java开发

java实现维吉尼亚加密算法,并可通过明文推算出准确密钥

2012-02-29 12:49 417 查看
题目要求是这样的,输入明文,输入密钥,用Vigenere加密算法进行加密,得到密文。然后通过明文和密文,再次反推出密钥。

基本上没有什么难点。就是反推密钥时,得到的有重复的密钥串,于是用了穷举法,对每种长度的密钥串子串进行测试,通过明文能够完全匹配出密文的,并且是第一次出现的,就取那个子串作为反推的密钥。

还有个问题没花时间解决,就是目前还不能处理输入的明文带空格的情况。

代码如下:

import java.util.Scanner;

public class Vigenere {

static char[] wordTable = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z' };

public static void main(String[] args) {

char[][] vigenereTable = creatVigenereTable();

Scanner sin = new Scanner(System.in);
System.out.println("请输入你想进行加密的明文:");
String mingwenStr = sin.nextLine();
char[] mingwen = mingwenStr.toCharArray();
System.out.println("请设置一个密钥:");
String miyaoStr = sin.nextLine();
char[] miyao = miyaoStr.toCharArray();

int mingwenLength = mingwen.length;
int miyaoLength = miyao.length;

char[] miwen = jiami(mingwenLength, miyaoLength, mingwen, miyao,
vigenereTable);
System.out.print("用维吉尼亚算法进行加密后的密文是:");
for (int s = 0; s < mingwenLength; s++) {
System.out.print(miwen[s]);
}
System.out.println();

char[] miyao111 = qiumiyao(mingwenLength, mingwen, miwen, vigenereTable);
System.out.print("根据密文推断密钥是:");
for(int i=0; i<miyao111.length; i++){
System.out.print(miyao111[i]);
}
System.out.println();
// for (int m = 0; m < 26; m++) {
// for (int n = 0; n < 26; n++) {
// System.out.print(vigenereTable[m]
);
// }
// System.out.println();
// }

}

public static char[][] creatVigenereTable() {

char[][] vigenereTable = new char[26][26];

int i = 0;
for (int x = 0; x < 26; x++) {
for (int y = 0; y < 26; y++) {
vigenereTable[x][y] = wordTable[i];
i++;
}
i = x + 1;
}
return vigenereTable;
}

private static char[] jiami(int mingwenLength, int miyaoLength,
char[] mingwen, char[] miyao, char[][] vigenereTable) {
// 现在开始加密
char[] miwen = new char[mingwenLength];
int miyaol = 0;

for (int mingwenl = 0; mingwenl < mingwenLength; mingwenl++) {

for (int wordTablel = 0; wordTablel < 26; wordTablel++) {

if (mingwen[mingwenl] == wordTable[wordTablel]) {

for (int wordTablel2 = 0; wordTablel2 < 26; wordTablel2++) {

if (miyao[miyaol] == wordTable[wordTablel2]) {

miwen[mingwenl] = vigenereTable[wordTablel][wordTablel2];
}
}
}
}

// 是miyaol+1,而不是miyaol,不然会报数组下标越界的错,找了很久的错,记住
if (miyaol + 1 <= miyaoLength - 1) {
miyaol++;
} else {
miyaol = 0;
}
}

return miwen;
}

private static char[] qiumiyao(int mingwenLength, char[] mingwen,
char[] miwen, char[][] vigenereTable) {
//先得到一个跟明文一样长度的密钥,稍后根据循环重复的部分判断密钥具体是什么
char[] miwenTest = null;
char[] miyaoTest = new char[mingwenLength];//测试密钥假设跟明文长度一样,因为最长不会超过这个长度
char[] miyao = null;//实际的密钥现在不知道长度,所以没有初始化
int mingwenl;
int miyaol=0;
for (mingwenl=0 ; mingwenl < mingwenLength; mingwenl++) {

for (int wordTablel = 0; wordTablel < 26; wordTablel++) {

if (mingwen[mingwenl] == wordTable[wordTablel]) {

for (int wordTablel2 = 0; wordTablel2 < 26; wordTablel2++) {

if(miwen[mingwenl] == vigenereTable[wordTablel][wordTablel2]) {
miyaoTest[miyaol] = wordTable[wordTablel2];
}

}
}
}
miyao = new char[mingwenl+1];//初始化密钥数组,还未赋值,此时长度假设的是跟测试到第几位明文的长度一样
System.arraycopy(miyaoTest, 0, miyao, 0, mingwenl+1);//把此时此刻的假设的跟测试到第几位明文的长度一样的假设密钥赋值给 上面定义的密钥数组,稍后测试
miwenTest = jiami(mingwenLength, miyaol+1, mingwen, miyao, vigenereTable);
String miwenA = String.valueOf(miwenTest);
String miwenB = String.valueOf(miwen);
if(miwenA.equals(miwenB)) {
break;
}
miyaol++;
}
return miyao;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: