2015-09-19 3 views
0

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

а -> б

к -> л

Затем во втором туре он должен попытаться

а -> С

K -> M

Проблема с символами состоит в том, что он включает в себя все виды странных символов, а когда вы сталкиваетесь с az и пытаетесь его заменить, он заменяется странным символом.

Любой, кто может помочь мне сделать какой-то круговой список из A-Z? В следующем фрагменте я создаю список, который содержит от a до z. В цикле выбирается символ, его индекс просматривается и «настраивается», и новый символ должен быть восстановлен. Но это не сработает. (Одна причина, по которой перечень является не круговой)

public static void decipher(){ 
    String cyphertext = "aVaqrprzoreoeratraWhyvhfraJnygreUbyynaqreqrgjrroebrefinaRqvguZnetbganneNzfgreqnzNaarjvytenntzrrxbzraznnezbrgabtrrarragvwqwrovwbznoyvwiraBznmnyurgzbrvyvwxuroorabzNaarabtrracnnejrxraqnnegrubhqrafpuevwsgRqvguSenaxvarraoevrsnnaTregehqAnhznaauhaiebrtrerohhezrvfwrvaSenaxshegnzZnva"; 
    char[] plaintext = new char[cyphertext.length()]; 

    List<Character> a2z = new ArrayList<Character>(26); 
    for (char c = 'A'; c <= 'Z'; c++){ 
     a2z.add(Character.valueOf(c)); 
    } 

    for(int i = 1; i < 26; i++){ 
     for(int j = 0; j < cyphertext.length(); j++){ 
      char currentChar = cyphertext.charAt(j); 
      int newCharIndex = a2z.indexOf(currentChar)+i; 
      plaintext[j] = a2z.get(newCharIndex); 
     } 
    } 
} 

ответ

0

Вам не нужен круговой список для обработки кромки. Кроме того, вы должны иметь в виду, что символы A-Z имеют значения ascii между 65-90 и a-z между 97-122. Вы могли создать два круглых списков, но они не нужны, потому что краевые случаи просты в обращении:

public static void main(String[] args) { 
    String cyphertext = "aVaqrprzoreoeratraWhyvhfraJnygreUbyynaqreqrgjrroebrefinaRqvguZnetbganneNzfgreqnzNaarjvytenntzrrxbzraznnezbrgabtrrarragvwqwrovwbznoyvwiraBznmnyurgzbrvyvwxuroorabzNaarabtrracnnejrxraqnnegrubhqrafpuevwsgRqvguSenaxvarraoevrsnnaTregehqAnhznaauhaiebrtrerohhezrvfwrvaSenaxshegnzZnva"; 
    char[] plaintext = new char[cyphertext.length()]; 

    // first shift 
    shiftLetters(cyphertext, plaintext, 1); 
    // update cyphertext with the intermediate result 
    cyphertext = new String(plaintext); 
    // second shift 
    shiftLetters(cyphertext, plaintext, 2); 
    // print result 
    System.out.println(new String(plaintext)); 

} 

private static void shiftLetters(String cyphertext, char[] plaintext, int shifts) { 
    for (int i=0; i<cyphertext.length(); i++){ 
     int tmp = cyphertext.charAt(i) + shifts; 
     tmp = handleEdgeCases(tmp); 
     plaintext[i] = (char)(tmp); 
    } 
} 

// here we handle the "circular" cases 
private static int handleEdgeCases(int tmp) { 
    if (tmp > 90 && tmp < 97) { 
     tmp = tmp - 90 + 65; 
    } else if (tmp > 122) { 
     tmp = tmp - 122 + 97; 
    } 
    return tmp; 
} 
+0

Но что, если вы переводите капитал V 12 раз, а его значение сдвигается с 86 на 98, а затем программа думает, что это нижний регистр b. – Nils

+0

Addon/Edit: (При использовании цикла) Но все работает. – Nils

+0

Одно небольшое дополнение, я думаю -90 + 65, результат которого -25 должен быть -26. В противном случае: a 'z' с значением ascii 122, сдвинутым с 1, становится 123. Затем в методе ребра вычитает 25 результат в 98, что является «b». Но это должно быть «а». – Nils

0

Проблема здесь:

int newCharIndex = a2z.indexOf(currentChar)+i; 
plaintext[j] = a2z.get(newCharIndex); 

декодированного характер здесь между 0 и 25. AZ ASCii идет от 65 до 90. Вы хотите переместить индекс в a2z в диапазоне от А до Я:

plaintext[j] = a2z.get(newCharIndex) + 'A'; 
+0

Я не уверен, если это так, потому что IndexOf (A) должна возвращать 0 , то + i делает это для примеров 1, тогда get (1) должен вернуть B как новый символ, который он делает. Проблема в том, что v смещается за пределы z. – Nils

1

Если я правильно вас понял, вы хотите подмена шифра перекладывать письма вверх N, упаковка из Z до A, делая буквы верхнего и нижнего регистра и оставляя все остальные символы неизменными.

E.g. если N равно 2:

a → c b → d ... x → z y → a z → b 
A → C B → D ... X → Z Y → A Z → B 

Нравится?

char[] text = "aVaqrprzoreoeratraWhyvhfraJnygreUbyynaqreqrgjrroebrefinaRqvguZnetbganneNzfgreqnzNaarjvytenntzrrxbzraznnezbrgabtrrarragvwqwrovwbznoyvwiraBznmnyurgzbrvyvwxuroorabzNaarabtrracnnejrxraqnnegrubhqrafpuevwsgRqvguSenaxvarraoevrsnnaTregehqAnhznaauhaiebrtrerohhezrvfwrvaSenaxshegnzZnva".toCharArray(); 
for (int n = 1; n < 26; n++) { 
    for (int i = 0; i < text.length; i++) { 
     char c = text[i]; 
     if (c >= 'A' && c <= 'Z') 
      text[i] = (char)('A' + (c - 'A' + n) % 26); 
     else if (c >= 'a' && c <= 'z') 
      text[i] = (char)('a' + (c - 'a' + n) % 26); 
    } 
} 
System.out.println(new String(text)); 

Выход

nIndecemberbrengenJuliusenWalterHollanderdetweebroersvanEdithMargotnaarAmsterdamAnnewilgraagmeekomenmaarmoetnogeeneentijdjebijomablijvenOmazalhetmoeilijkhebbenomAnnenogeenpaarwekendaartehoudenschrijftEdithFrankineenbriefaanGertrudNaumannhunvroegerebuurmeisjeinFrankfurtamMain 

Конечно, вы понимаете, что сдвиг на 1, затем 2, затем 3, ... и, наконец, на 26, то же самое (1 + 2 + 3 + ... + 26), что равно 351 и 351 % 26 = 13.

И сдвиг на 13 означает, что кодирование и декодирование являются одной и той же операцией.


Объяснение

Если вы перемещаетесь на 26, вы сдвигая точно полный круг, т.е. a → a b → b ..., так что это так же, как не меняется, следовательно, любое смещение N> = 26 является такие же, как N% 26, например N = 28 - это то же самое, что и N = 2.

Сдвиг на 1 a → b затем на 2 b → d затем на 3 d → g, такое же, как сдвигом на 1 + 2 + 3 = 6 a → g. Таким образом, сдвиг на 1 + 2 + ... + 26 = 351 совпадает с сдвигом на 351% 26 = 13.

Если переменная c является заглавной буквой (AZ), то c - 'A' является числом от 0 и 25. Добавив примерный сдвиг 6, вы получите номер 6-31. Делая остаток на 26 (% 26) дает 6-25,0-5, а затем + 'A' дает G-Z,A-F, что означает A → G B → H ... Y → E Z → F, каждую букву, сдвинутую 6.

То же самое для строчных букв.

+0

Я решил, что хочу сдвинуть на 1, затем на 2 и т. Д., Чтобы напечатать все промежуточные результаты. Итак, чтобы проверить, какой результат фактически дал разумный результат. Я действительно не понимаю, почему сумма сдвигов (351) mod 26 равна используемому количеству сдвигов. – Nils

+0

Я также не получаю часть в выражении if else if. – Nils

Смежные вопросы