我有一个非常简单的小程序,它读取一个整数,加密它,然后解密它,但无论出于何种原因,有时它给了我正确的答案,而有时它没有。代码:
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
,有时会添加n
和plaintext value from [0 - n-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;
}