Если вы не знакомы с шифром. Идея состоит в том, чтобы иметь возможность кодировать сообщение, перемещая буквы в алфавите. Ex. d сдвиг 3 -> a. Затем сможете декодировать сообщение с использованием метода трещины. Метод трещины делает массив полным значений квадрата (по сравнению с естественными алфавитными частотами в таблице) для каждого возможного сдвига (его индекс) и проверяет, имеет ли значение сдвига наименьшее значение. Затем он принимает это значение и декодирует его, используя эту величину сдвига.Сложность с Цезарем Шифр Ши-Squared
Проблема, я получаю наименьшее значение квадрата квадрата в неправильном адресе массива, чтобы его можно было точно декодировать. Я не ищу, чтобы кто-то дал мне ответ, просто для того, где я должен посмотреть в своем коде, чтобы внести исправление.
Заранее спасибо.
import java.util.Arrays;
public class Cipher {
//alphabet frequency
static double[] table = {8.2, 1.5, 2.8, 4.3, 12.7, 2.2, 2.0, 6.1, 7.0, 0.2, 0.8, 4.0, 2.4, 6.7,
7.5, 1.9, 0.1, 6.0, 6.3, 9.1, 2.8, 1.0, 2.4, 0.2, 2.0, 0.1};
//convert letter to number
static int let2nat(char c)
{
return ((int) c) - 97;
}
//convert number to letter
static char nat2let(int code)
{
return (char) (code + 97);
}
//shift a letter to another letter shftAmt spaces away
static char shift(int shftAmt, char c)
{
if (let2nat(c) < 0 || let2nat(c) > 25)
return c;
return nat2let((let2nat(c) + shftAmt) % 26);
}
//encodes a string using the given shift amount
static String encode(int shftAmt, String str)
{
char[] encodedStr = new char[str.length()];
for(int i = 0; i < str.length(); i++)
encodedStr[i] = shift(shftAmt, str.charAt(i));
return new String(encodedStr);
}
//performs the inverse method to encode
static String decode(int shftAmt, String str)
{
char[] decodedStr = new char[str.length()];
for(int i = 0; i < str.length(); i++)
decodedStr[i] = shift(0 - shftAmt, str.charAt(i));
return new String(decodedStr);
}
//determines how many lowercase letters are in the string str
static int lowers(String str)
{
int count = 0;
for(int i = 0; i < str.length(); i++)
if(let2nat(str.charAt(i)) >= 0 && let2nat(str.charAt(i)) <= 25)
count++;
return count;
}
//calculates the number of a character in a string
static int count(char c, String str)
{
int counter = 0;
for(int i = 0; i < str.length(); i++)
if(c == str.charAt(i))
counter++;
return counter;
}
//calculates the percent off num1 to num2
static double percent(int num1, int num2)
{
return ((double) num1/num2 * 100);
}
//find the ratio frequency of all letters in the string str
static double[] freqs(String str)
{
double[] count = new double[26];
for(int i = 0; i < str.length(); i++)
if(let2nat(str.charAt(i)) >= 0 && let2nat(str.charAt(i)) <= 25)
count[let2nat(str.charAt(i))]++;
for(int i = 0; i < 26; i++)
count[i] = percent((int)count[i], lowers(str));
return count;
}
//rotates a list n places to the left
static double[] rotate(int n, double[] list)
{
int j = 0;
while(j<n){
double starter = list[0];
//shift one left
for(int i = 0; i < list.length-1; i++)
list[i] = list[i+1];
list[list.length-1] = starter;
j++;
}
return list;
}
//calculates the chi square value
static double chisqr(double[] os)
{
double chitotal = 0;
for(int i = 0; i < os.length; i++)
chitotal += ((Math.pow((os[i] - table[i]), 2))/table[i]);
return chitotal;
}
//returns the first position at whcih a value occurs,if returns 999999 then it doesnt exist in the array
static int position(double a, double[] list)
{
for(int i = 0; i < list.length; i++)
if(list[i] == a)
return i;
return 999999;
}
static String crack(String str)
{
double[] frequencies = freqs(str);
double[] chisqrValues = new double[26];
for(int i = 0; i < 26; i++)
chisqrValues[i] = chisqr(rotate(i, frequencies));
int smallestIndex = 0;
for(int i = 1; i < 26; i++)
if(chisqrValues[i] < chisqrValues[smallestIndex])
smallestIndex = i;
return decode(smallestIndex, str);
}
public static void main(String[] args)
{
System.out.println(crack(encode(3, "haskellisfun")));
}
}
Тестирование показало, что ваша смена отрицательных чисел сломана - проверьте ее самостоятельно и отлаживайте. Простой цикл, который проходит через алфавит и сдвигается в положительном и отрицательном направлении и распечатывает его, покажет вам это. –
Это связано с тем, что отрицательные числа не изменяются до положительных чисел. Вам нужно модифицировать int, добавить значение mod (26, которое я перехожу на const), и изменить его снова. Но это не источник вашей основной ошибки. –
[Например] (http://pastebin.com/wNheWu6u) –