-1

I'm an Engineering Student and I'm stuck on this part of the Affine Cypher.

import java.util.Scanner;
public class abcd {
    public static int a, b;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter key(a,b): ");
        a = sc.nextInt();
        b = sc.nextInt();
        Scanner hj = new Scanner(System.in);
        System.out.print("Enter String: ");
        String word = hj.nextLine();
        sc.close();
        hj.close();

        
        System.out.println("Cyphered text: " + cypher(word));
        System.out.println("Decyphered text: " + decypher(cypher(word)));
        
    }
    
    public static String cypher(String plaintext) {

        
        String CT = "";
        for (int i = 0; i < plaintext.length(); i++) {
            char x = plaintext.charAt(i);
            int val = (char)x-97;
            int C = ((a* val + b)%26);
            char n = (char) (C + 97);
            CT = CT + n;
            
        }
        return CT;
        
        
    }
    
    public static int inv (int a, int b) {
        a=a%b;
        for (int x = 1; x<26; x++) {
            if ((a*x)%26==1) {
                return x;
            }
        }
        return 1;
    }
    
    public static String decypher(String cyphertext) {
        String t = "";

        for (int i = 0; i<cyphertext.length(); i++) {
            char x = cyphertext.charAt(i);
            int val = (char)x - 97;
            int D = ((inv(a, 26)*(val-b))%26);
            char n = (char)(D + 97);
            t = t + n;
                    
        }return t;
    }

}

The cyphered text shows the desired output but the deciphered text doesn't match the original text.

Here is my console input and output:

Enter key(a,b):
7
2
Enter String: hello
Cyphered text: zebbw
Decyphered text: heRRo

enter image description here

I was expecting the deciphered text to match the original text since that is what it was supposed to do.

  • [Please do not upload images of code/data/errors.](//meta.stackoverflow.com/q/285551) Instead [edit] your question to contain the output you get as (properly formatted) plain text. – Joachim Sauer Feb 03 '23 at 14:55
  • 2
    Capital `R` is encoded as 82, which is smaller than 97, suggesting that `D` became negative in the decryption formula, that's about as far as I debugged. Figure out why and fix that. You might be running into the fact that [`%` isn't exactly the same as `mod`](https://stackoverflow.com/questions/5385024/mod-in-java-produces-negative-numbers), especially when it comes to negative numbers. – Joachim Sauer Feb 03 '23 at 14:59
  • % in Java is the remainder operation, which doesnt do complements. what I did to circumvent that was a while loop that while the number is negative, add the modulo value to it., you could probably make it a helper method to convert all your negatives after using % – Tan Yu Hau Sean Feb 03 '23 at 15:08
  • @JoachimSauer I edited on the OP's behalf, so the image is now available as text. – EJoshuaS - Stand with Ukraine Feb 03 '23 at 17:20

1 Answers1

0

As Joachim Sauer and Tan Yu Hau Sean suggest, % does things you may not expect on negative numbers. If a is negative, a%b will be a number between -b and 0.

If you add a method like this

public static int mod(int a, int b) {
    return (a%b+b)%b;
} 

and replace your instances of % with calls to it, e.g.:

  int C = mod(a* val + b,26);

things will work a lot better.

teapot418
  • 1,239
  • 1
  • 3
  • 9
  • [`Math.floorMod()`](https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/Math.html#floorMod(int,int)) would also work. – Joachim Sauer Feb 03 '23 at 19:38