Мне нужно реализовать вариант шифра Виженера. Я получил часть шифрования без проблем, но у меня есть ошибка в коде расшифровки, и я не понимаю, что я делаю неправильно.
Требования:
ключ может содержать только
A
-Z
(верхний регистр)кодовые значения для ключевых символов: 0 для A, 1 для B, ... и 25 для Z.
не кодировать символ, если код ‹ 32 (сохранить управляющие символы)
зашифрованный код символа = исходный код символа + ключевой код символа
окончательный зашифрованный символ должен быть между 32 и 126, исключительно поэтому, если окончательный зашифрованный символ> 126, его необходимо вернуть в диапазон 32–126, добавив 32 к значению, а затем вычтя 126
Код шифрования:
// it works ok
// I have tested it with some provided strings and the results are as expected
public String encrypt(String plainText)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < plainText.length(); i++) {
char c = plainText.charAt(i);
if (c >= 32) {
int keyCharValue = theKey.charAt(i % theKey.length()) - 'A';
c += keyCharValue;
if (c > 126) {
c = (char) (c + 32 - 126);
}
}
sb.append(c);
}
return sb.toString();
}
Код расшифровки:
// there probably is an off-by-one error somewhere
// everything is decrypted ok, except '~' which gets decrypted to ' ' (space)
public String decrypt(String cipherText)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cipherText.length(); i++) {
char c = cipherText.charAt(i);
if (c >= 32) {
int keyCharValue = theKey.charAt(i % theKey.length()) - 'A';
c -= keyCharValue;
if (c < 32) {
c = (char) (c + 126 - 32);
}
}
sb.append(c);
}
return sb.toString();
}
Пример (с ключом ABCDEFGHIJKLMNOPQRSTUVWXYZ
):
оригинал
~~~~~~~~~~~~~~~~~~~~~~~~~~
зашифровано
~!"#$%&'()*+,-./0123456789
расшифровано
~
('~' с последующими пробелами)
РЕДАКТИРОВАТЬ:
Вот код, который я использую для тестирования (он проверяет каждый символ от 0 до 126, повторяющийся как строка):
public static void main(String[] args) {
int passed = 0;
int failed = 0;
String key = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int c = 0; c <= 126; c++) {
StringBuilder sbString = new StringBuilder();
for (int i = 0; i <= 25; i++) {
sbString.append((char) c);
}
String original = sbString.toString();
Cipher cipher = Cipher(key);
String encrypted = cipher.encrypt(original);
String decrypted = cipher.decrypt(encrypted);
if (!original.equals(decrypted)) {
failed++;
System.out.println("--FAILED--");
System.out.println(original);
System.out.println(encrypted);
System.out.println(decrypted);
} else {
passed++;
}
}
int tests = passed + failed;
System.out.println(tests + " tests");
System.out.println("passed: " + passed);
System.out.println("failed: " + failed);
}