Java:扫描程序问题?

时间:2016-03-01 01:59:42

标签: java while-loop java.util.scanner caesar-cipher

我有一个非常简单的小程序,它读取一个整数,加密它,然后解密它,但无论出于何种原因,有时它给了我正确的答案,而有时它没有。代码:

public class Cipher {

    public static void main(String[] args) {

        System.out.println("Welcome to Caesar Cipher Demo:");
        Scanner scanner = new Scanner(System.in);
        CaesarCipher cipher = new CaesarCipher();
        int a, n, x, y;
        int i = 1;
        while(true) {
            System.out.println("====== General Test ======");
            System.out.println("Please specify the following numbers:");
            System.out.printf("n - ");
            n = scanner.nextInt();
            scanner.nextLine();
            System.out.print("a - ");
            a = scanner.nextInt();
            scanner.nextLine();
            cipher.setN(n);
            cipher.setA(a);
            //scanner.nextLine();
            System.out.printf("plaintext value from [0 - %d] - ", (n-1));
            x = scanner.nextInt();
            y = cipher.encrypt(x);
            System.out.printf("ciphertext value - %d%n", y);

            x = cipher.decrypt(y);
            System.out.printf("back to plaintext value - %d%n", x);
            scanner.nextLine();

            System.out.printf("Continue? (1 for yes, 0 for no) - ");
            i = scanner.nextInt();
            scanner.nextLine();
            if(i == 0) break;
        }
        while(true){
            System.out.println("====== Text Message Test ======");
            cipher.setN(26);
            System.out.printf("key [0-25] - ");
            a = scanner.nextInt();
            scanner.nextLine();
            while(a < 0 || a > 25){
                System.out.printf("key must be from [0-25] - ");
                a = scanner.nextInt();
                scanner.nextLine();
            }
            cipher.setA(a);
            System.out.printf("plaintext (use English alphabet)- ");

            String plaintext = scanner.nextLine();
            plaintext = plaintext.toLowerCase();
            String ciphertext = cipher.encrypt(plaintext);
            System.out.printf("ciphertext - %s%n", ciphertext);

            plaintext = cipher.decrypt(ciphertext);
            System.out.printf("plaintext - %s%n", plaintext);

            System.out.printf("Continue? (1 for yes, 0 for no) - ");
            i = scanner.nextInt();
            scanner.nextLine();
            if(i == 0) break;
        }
    }
}

class CaesarCipher {
    private int a;
    private int n;
    private char[] letters;

    public CaesarCipher() {
        this.letters = new char[]{'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'};
    }

    public int getA() {
        return a;
    }

    public int getN() {
        return n;
    }

    public void setA(int a) {
        this.a = a;
    }

    public void setN(int n) {
        this.n = n;
    }

    public int encrypt(int x){
        if (x >= n){
            System.out.println("X must be less than "+n+"-1");
        }

        return (a+x) % n;

    }

    public int inverseOf(int e){
        return (n - e %n);
    }

    public int decrypt(int y){
        if (y >= n) {
            System.out.println("N must be "+ n +"-1");
        }

        return (inverseOf(a) + y % n);
    }

    public String encrypt(String plaintext){
        char[] ciphertext= new char[plaintext.length()];
        for (int j = 0; j<plaintext.length();j++) {
            char c = plaintext.charAt(j);
            int index = c- 'a';
            if (index < 0 || index > 25) {
                System.out.println("Illegal character!");
                System.exit(1);
            }
            index = encrypt(index);
            ciphertext[j] = letters[index];
        }
        return new String(ciphertext);

    }

    public String decrypt(String ciphertext){
        char[] plaintext = new char[ciphertext.length()];
        for (int j = 0; j < ciphertext.length();j++) {
            char c = ciphertext.charAt(j);
            int index = c- 'a';
            index = decrypt(index);
            plaintext[j] = letters[index];
        }
        return new String(plaintext);
    }
}

输出我得到:

    Welcome to Caesar Cipher Demo:
====== General Test ======
Please specify the following numbers:
n - 54
a - 44
plaintext value from [0 - 53] - 15
ciphertext value - 5
back to plaintext value - 15
Continue? (1 for yes, 0 for no) - 1
====== General Test ======
Please specify the following numbers:
n - 78
a - 55
plaintext value from [0 - 77] - 7
ciphertext value - 62
back to plaintext value - 85
Continue? (1 for yes, 0 for no) - 1
====== General Test ======
Please specify the following numbers:
n - 55
a - 54
plaintext value from [0 - 54] - 6
ciphertext value - 5
back to plaintext value - 6
Continue? (1 for yes, 0 for no) - 1
====== General Test ======
Please specify the following numbers:
n - 632
a - 43
plaintext value from [0 - 631] - 66
ciphertext value - 109
back to plaintext value - 698
Continue? (1 for yes, 0 for no) - 1
====== General Test ======
Please specify the following numbers:
n - 25
a - 3
plaintext value from [0 - 24] - 5
ciphertext value - 8
back to plaintext value - 30
Continue? (1 for yes, 0 for no) - 

如您所见,有时会返回正确的back to plaintext value,有时会添加nplaintext value from [0 - n-1]。我认为这是由扫描仪问题引起的,但无法确定问题的确切位置。我希望另一双眼睛能看到我无法做到的事情。谢谢你的时间,我真的很感激!

1 个答案:

答案 0 :(得分:1)

我不确定您在解密函数中尝试做什么,尤其是方法inverseOf。但这不正确。你在解密函数中想要的只是从加密值中减去密钥(然后使用模运算符将其保持在正确的范围内,并且额外检查它是否为负值,因为模运算符本身就是不足以将值保持在范围的底端

public int decrypt(int y) {
    if (y >= n) {
        System.out.println("N must be " + n + "-1");
    }

    if (y < a)
        return (y - a + n) % n;
    else
        return (y - a) % n;
}