-1

Steps for Deciphering the message

  1. remove 3 at end of the string
  2. replace ASCII values at even places(number clusters) with corresponding characters value.
  3. replace * with spacing " ".
  4. reverse the string
  5. swap case of string- lowercase to upper case and vice versa.

Sample input: ?85O89*69R65*87O104*33I1043 Require output: Hi! How are you? This is the whole method that I have written.

public String deciphering(String ciphered) {
        StringBuilder a = new StringBuilder(ciphered);
        StringBuilder b = a.deleteCharAt(a.length()-1);
        char[] ch = new char[b.length()];
        StringBuilder c = new StringBuilder();
        for (int i = 0; i < b.length(); i++) {
            ch[i] = b.charAt(i);
        }
        for (int i = 0; i < ch.length; i++) {
            if(!Character.isDigit(ch[i]))
            {
                c.append(ch[i]);
            }else
            {
                String temp = new String();
                while(Character.isDigit(ch[i]) &&(i<b.length())){
                   temp = temp + ch[i];
                   i++;
               }
                int number = Integer.parseInt(temp);
                char p = (char)number;
               c.append(p);
            }
        }

        String d = c.toString();
        String e = d.replace('*', ' ');
        StringBuffer f = new StringBuffer(e);
        StringBuffer g = f.reverse();
        for (int i = 0; i < g.length(); i++) {

                if (Character.isLowerCase(g.charAt(i))){
                    char x = Character.toUpperCase(g.charAt(i));
                    g.setCharAt(i, x);
                } else if (Character.isUpperCase(g.charAt(i))) {
                    char x = Character.toLowerCase(g.charAt(i));
                    g.setCharAt(i, x);
                }
        }

        return g.toString();
    }
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
Biswaroop
  • 1
  • 1
  • 1
    Your requirement is unclear; it's definitely not "even positions", since your first '3' is in an even position and the second '3' in an odd one. – Andrew McGuinness Sep 27 '21 at 15:38
  • Actually, it is like an encrypted string where each number cluster represents an ASCII character – Biswaroop Sep 27 '21 at 15:40
  • FYI, the `char` type in Java is legacy, essentially broken. As a 16-bit value, `char` is incapable of representing most characters. Learn to use [code point](https://en.wikipedia.org/wiki/Code_point) integer numbers instead. – Basil Bourque Sep 27 '21 at 15:42
  • 1
    @Biswaroop: so what would `'1', '1', '1', '1'` be? 111 followed by 1? Or 11 followed by 11? Or 4 times a 1? It's still unclear how this is supposed to work and therefore it's unclear what your logic should be. – Joachim Sauer Sep 27 '21 at 15:52
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Oct 05 '21 at 11:13

2 Answers2

0

You are incrementing i twice past the last digit of a chunk - when you exit your inner loop i is indexing the first non-digit character, then when you reach the end of the for loop body, the for loop is incrementing i again.

Andrew McGuinness
  • 2,092
  • 13
  • 18
0

It may be better to split the input string into parts with non-digit delimiters and keep the delimiters using the following regular expression (using look-ahead and look-behind as described here) after removing the last character:

str.substring(0, str.length() - 1).split("(?<=\\D)|(?=\\D)")

Then Stream API may be used to convert each string into a separate character and insert these characters into prepared StringBuilder to implement reverse order in the result:

public static String decipher(String str) {
    
    StringBuilder sb = new StringBuilder(str.length());
    
    Arrays.stream(
            str.substring(0, str.length() - 1).split("(?<=\\D)|(?=\\D)")
        )
        .map(p -> p.matches("\\d+") ? (char) Integer.parseInt(p): p.charAt(0))
        .map(c -> c == '*' ? ' ' 
            : Character.isLowerCase(c) ? Character.toUpperCase(c) 
            : Character.isUpperCase(c) ? Character.toLowerCase(c)
            : c
        )
        .forEach(c -> sb.insert(0, c));
        
    return sb.toString();
}

Test:

System.out.println(decipher("?85O89*69R65*87O104*33I1043"));

Output:

Hi! How are you?
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42