import java.util.ArrayList;
public class Vegenere {
public static void main(String[] args) {
// TODO Auto-generated method stub
String encrypt = "OCWYIKOOONIWUGPMXWKTZDWGTSSAYJZWY"
+ "EMDLBNQAAAVSUWDVBRFLAUPLOOUBFGQHGCSCMGZL"
+ "ATOEDCSDEIDPBHTMUOVPIEKIFPIMFNOAMVLPQFXE"
+ "JSMXMPGKCCAYKWFZPYUAVTELWHRHMWKBBNGTGUVT"
+ "EFJLODFEFKVPXSGRSORVGTAJBSAUHZRZALKWUOWH"
+ "GEDEFNSWMRCIWCPAAAVOGPDNFPKTDBALSISURLNP"
+ "SJYEATCUCEESOHHDARKHWOTIKBROQRDFMZGHGUCE"
+ "BVGWCDQXGPBGQWLPBDAYLOOQDMUHBDQGMYWEUIK";
ArrayList<String> theEncrypt = new ArrayList();
ArrayList<String> Key,answer;
for(int i = 0;i<encrypt.length();i++)
{
theEncrypt.add(String.valueOf(encrypt.charAt(i)));
}
Encrypt en = new Encrypt(theEncrypt);
Key = en.ShowKey();
answer = en.ShowAnswer();
en.DoEncrypt();
System.out.println(Key);
System.out.println(en.keyLength);
System.out.println(answer);
}
}
import java.util.ArrayList;
import java.lang.*;
public class Encrypt {
ArrayList<String> key = new ArrayList();
int keyLength;//密钥长度
double[] keyProbability = {0.082,0.015,0.028,0.042,
0.127,0.022,0.020,0.061,0.070,0.001,0.008,
0.040,0.024,0.068,0.075,0.019,0.001,0.060,
0.063,0.090,0.028,0.010,0.024,0.020,0.001
,0.001};
double[] theKeyProbability = new double[26];
ArrayList<String> theEncrypt; //密文
ArrayList<String> theEncrypt2; //用于计算重合指数的密文2
ArrayList<String> answer = new ArrayList();
//构造函数
public Encrypt(ArrayList<String> theEncrypt){
this.theEncrypt = theEncrypt;
theEncrypt2= new ArrayList<>(theEncrypt);
}
//解密
public ArrayList<String> DoEncrypt(){
int likeNumber=0,likeNumberBuffer=0;
int firstnumber = 6;
//确定密匙长度
for(int i=firstnumber;i<theEncrypt.size();i++){
likeNumberBuffer=0;
i=firstnumber;
//int i=7;
for(int j =0 ;i<theEncrypt.size();j++,i++){
if(theEncrypt.get(i).equals(theEncrypt2.get(j)))
{
likeNumberBuffer++;
}
}
if(likeNumber<likeNumberBuffer)
{
likeNumber=likeNumberBuffer;
keyLength = firstnumber;
}
firstnumber++;
}
return theEncrypt;
}
//确定密钥值
public ArrayList<String> ShowKey()
{
for(int i=0;i<6;i++){
int[] a= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
double sumNumber=0.0;
//if(theEncrypt.get(i).equals(theEncrypt2.get(j)))
for(int j=i;j<theEncrypt.size();j = j+6)
{
switch (theEncrypt.get(j)){
case "A":a[0]++;break;
case "B":a[1]++;break;
case "C":a[2]++;break;
case "D":a[3]++;break;
case "E":a[4]++;break;
case "F":a[5]++;break;
case "G":a[6]++;break;
case "H":a[7]++;break;
case "I":a[8]++;break;
case "J":a[9]++;break;
case "K":a[10]++;break;
case "L":a[11]++;break;
case "M":a[12]++;break;
case "N":a[13]++;break;
case "O":a[14]++;break;
case "P":a[15]++;break;
case "Q":a[16]++;break;
case "R":a[17]++;break;
case "S":a[18]++;break;
case "T":a[19]++;break;
case "U":a[20]++;break;
case "V":a[21]++;break;
case "W":a[22]++;break;
case "X":a[23]++;break;
case "Y":a[24]++;break;
case "Z":a[25]++;break;
}
}
for(int n=0;n<26;n++)
{
sumNumber = sumNumber+a[n];
}
for(int n=0;n<26;n++)
{
theKeyProbability[n] = a[n]/sumNumber;
}
int min = 0;
double minChongHeZhiShu = 0.0;
for( int j = 0;j<26;j++)
{
double chongHeZhiShu = 0.0;
for(int n = 0;n<26;n++)
{
chongHeZhiShu = chongHeZhiShu +keyProbability[Math.floorMod((n+j),26)]*theKeyProbability[n];
}
//选择重合指数最接近0.065的偏移量
if(Math.abs(minChongHeZhiShu-0.065)>Math.abs(chongHeZhiShu-0.065))
{
minChongHeZhiShu = chongHeZhiShu;
min = j;
}
}
key.add(String.valueOf((char)('a'+(int)(26-min))));//26-min是为了返回平移量的模,此时的偏移量才是真的偏移量
}
return key;
}
//返回解密结果
public ArrayList<String> ShowAnswer()
{
for(int i = 0;i<theEncrypt.size();i++)
{
int a = Math.floorMod(theEncrypt.get(i).charAt(0)+32-key.get(Math.floorMod(i, 6)).charAt(0), 26);
char b = (char)(a+'a');
answer.add(String.valueOf(b));
}
return answer;
}
}