Task:

Encrypt any plaintext over the Latin alphabet using a single letter replacement cipher

Code:

String str = "BE_HAPPY"; String[] bytes = new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " " }; int[] key = new int[] { 18, 22, 11, 7, 15, 19, 1, 23, 20, 26, 3, 14, 25, 4, 9, 5, 2, 24, 21, 6, 0, 8, 13, 12, 16, 10, 17 }; String a = ""; String m = ""; for (String ma : str.split("")) { m = m + bytes[key[Arrays.asList(bytes).indexOf(ma)]]; } System.out.print(m); 

Mistake:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 at L5.lab5.main (lab5.java:24)

What to do?

  • And what do you want to get? What should your code do? - Tivyram
  • cryptography task. must encrypt string. - Vlad Ilyashenko
  • Add the condition of the problem in the question, this information will speed up the response - Tivyram
  • Encrypt the text above the Latin alphabet in addition to the code of the single letter of the text. - Vlad Ilyashenko
  • I made the task manually, but I still need the code. - Vlad Ilyashenko

3 answers 3

There is no underscore in the bytes array, so Arrays.asList(bytes).indexOf(ma) returns -1. After trying to access the -1 element of the array, the key throws a java.lang.ArrayIndexOutOfBoundsException: -1

  • one
    Only here the question "What to do?" This does not give an answer. So while the author of the full condition of the problem does not add, do not give a complete answer. - Regent
  • @Regent agree - Victor
  • thank. That's right_) - Vlad Ilyashenko
  • @ Vlada Ilyashenko if the answer suits you, do not forget to mark it as appropriate (checkmark to the left of the answer). - Regent

As already mentioned, the problem is in the _ symbol, for which there is no match in the "encryption table".

Let me assume that the characters that are not in the "encryption table" should remain in its original form. Then, given a small optimization, the code might look like this:

 String str = "BE_HAPPY"; Character[] chars = new Character[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ' }; List<Character> charsList = Arrays.asList(chars); int[] key = new int[] { 18, 22, 11, 7, 15, 19, 1, 23, 20, 26, 3, 14, 25, 4, 9, 5, 2, 24, 21, 6, 0, 8, 13, 12, 16, 10, 17 }; StringBuilder sb = new StringBuilder(str.length()); for (char ch : str.toCharArray()) { int charIndex = charsList.indexOf(ch); char resultChar = charIndex >= 0 ? chars[key[charIndex]] : ch; sb.append(resultChar); } System.out.println(sb.toString()); //WP_XSFFQ 

    I assume that the cipher and the text are part of the task. also suppose that most likely the _ character and the space is the same, since this will correspond to the condition of the problem.

    Let me optimize your code a little and suggest other solutions:

     @Test public void test() { String str = "BE_HAPPY"; // с массивом примитивов будет удобнее работать char[] bytes = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_' }; int[] key = { 18, 22, 11, 7, 15, 19, 1, 23, 20, 26, 3, 14, 25, 4, 9, 5, 2, 24, 21, 6, 0, 8, 13, 12, 16, 10, 17 }; // а зачем была нужна эта переменная? // String a = ""; // см ниже. строим словарь для варианта 1 char[] caesar = new char[255]; for(int i = 0; i < bytes.length; i++) { caesar[bytes[i]] = bytes[key[i]]; } // запомним длину строки чтобы не вызывать метод в цикле int n = str.length(); // будем складывать все в буффер(ы) StringBuilder m = new StringBuilder(n); StringBuilder m1 = new StringBuilder(n); StringBuilder m2 = new StringBuilder(n); for (int i = 0; i < n; i++) { // берем символ прямо из строки не заморачиваясь разбиванием строки на массив char ma = str.charAt(i); // вариант 0: сканируем массив символов не переводя его в список каждую итерацию for(int j = 0; j < bytes.length; j++) { if(ma == bytes[j]) { m.append(bytes[key[j]]); break; } } // тут есть альтернативы: // вариант 1. если надо было бы зашифровать большой текст, то вместо сканирования лучше использоваит словарь m1.append(caesar[ma]); // конец варианта 1 // вариант 2. если мы уверены, что алфавит всегда латиница по порядку, то можно использовать смещение символа int offs; // if(ma >= 'A' && ma <= 'Z') offs = ma - 'A'; else offs = bytes.length-1; m2.append(bytes[key[offs]]); // конец варианта 2 } System.out.println(m); System.out.println(m1); System.out.println(m2); }