Shift Cipher ошибочно сдвигает некоторые символы

Я пытаюсь использовать шифр сдвига для декодирования сообщения. Некоторые из моих персонажей хорошо переводят, а другие нет. Я не могу понять, в чем проблема.

public class ShiftCipher {

public static void main(String[] args) {

    System.out.println(cipher("F30MDAAFEMA1MI0EF0D9", 14));
}

static String cipher(String msg, int shift){
    String characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
    String DecryptedMessege = "";
    String DecryptedChar = "";
    int trueShift;
    boolean in = false; //Debugging
    for(int x = 0; x < msg.length(); x++){
        for (int y = 0; y < characters.length(); y++ ) {
            if (msg.charAt(x) == characters.charAt(y)){
              if (y+shift <= characters.length()){
                trueShift = y + shift;
                in = true; //Debugging
              }
              else {
                trueShift = shift - (characters.length() - y);
                in = false; //Debugging
              }

            DecryptedChar = new StringBuilder().append(characters.charAt(trueShift)).toString(); 
            System.out.println(DecryptedChar + " " + in + " " + trueShift); //Debugging                 
            }
        }
            DecryptedMessege = DecryptedMessege + DecryptedChar;
    }
    return DecryptedMessege;
}
}

Некоторые ранние буквы ошибочно смещены на -1. Выходные данные должны читать "КОРНИ ЗАПАДА", но вместо этого следует читать "TGD ROOTS OE WDSTDRN".

У кого-нибудь есть идеи, почему это не работает? Любой вклад приветствуется.

1 ответ

Решение

Используйте по модулю % (остаток от деления int): по модулю 4 будет 0, 1, 2, 3, 0, 1, 2, 3, ...

Вместо if-then-else легче сделать следующее.

          trueShift = (y + shift) % characters.length();

Или, если y+shift может быть отрицательным (тогда trueShift тоже станет отрицательным), лучше:

          int n = characters.length();
          trueShift = (y + shift + n) % n;

В остальной части trueShift не был симметричным (инъективным, не биективным): расшифровывать (encrypt(s))!= s. Если 0,1,2,3 отображается на 0,1,1,0, возникает проблема.


static String cipher(String msg, int shift){
    String characters = "01234556789ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
    int n = characters.length();
    StringBuilder decryptedMessage = new StringBuilder();
    for (int x = 0; x < msg.length(); x++) {
        char ch = msg.charAt(x);
        int y = characters.indexOf(ch);
        if (y != -1) {
            int trueShift = (y + shift + n) % n;
            ch = characters.charAt(trueShift);
        }
        decryptedMessage.append(ch);
    }
    return decryptedMessage.toString();
}
Другие вопросы по тегам