Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Caesar密码Java程序可以';不要超过23档_Java_Caesar Cipher - Fatal编程技术网

Caesar密码Java程序可以';不要超过23档

Caesar密码Java程序可以';不要超过23档,java,caesar-cipher,Java,Caesar Cipher,我正在创建一个程序来执行一个凯撒密码,当我按enter键时,它会将单词中的字母移动一次,并提示用户再次移动或退出 它一直工作到23个班次,然后出于某种原因开始使用非字母符号,我不知道为什么会发生这种情况 有什么建议吗?代码如下: import java.io.File; import java.io.IOException; import java.util.Scanner; public class Cipher { public static void main(String[]

我正在创建一个程序来执行一个凯撒密码,当我按enter键时,它会将单词中的字母移动一次,并提示用户再次移动或退出

它一直工作到23个班次,然后出于某种原因开始使用非字母符号,我不知道为什么会发生这种情况

有什么建议吗?代码如下:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class Cipher {

    public static void main(String[] args) {

        // encrypted text
        String ciphertext;

        // input from keyboard
        Scanner keyboard = new Scanner(System.in);

        if (args.length > 0) {
            ciphertext = "";
            try {
                Scanner inputFile = new Scanner(new File(args[0]));
                while (inputFile.hasNext())
                    ciphertext += inputFile.nextLine();
            } catch (IOException ioe) {
                System.out.println("File not found: " + args[0]);
                System.exit(-1);
            }
        } else {
            System.out.print("Please enter text--> ");
            ciphertext = keyboard.nextLine();
        }

        // -----------------------------------------------------------------

        int distance = 0;  // how far the ciphertext should be shifted
        String next = "";  // user input after viewing
        while (!next.equals("quit")) {
            String plaintext = "";
            distance += 1;
            for (int i = 0; i < ciphertext.length(); i++) {
                char shift = ciphertext.charAt(i);
                if (Character.isLetter(shift)) {
                    shift = (char) (ciphertext.charAt(i) - distance);
                    if (Character.isUpperCase(ciphertext.charAt(i))) {
                        if (shift > '0' && shift < 'A') {
                            shift = (char) (shift + 26);
                            plaintext += shift;
                        } else {
                            plaintext += shift;
                        }
                    }
                    if (Character.isLowerCase(ciphertext.charAt(i))) {
                        if (shift > '0' && shift < 'a' && ciphertext.charAt(i) < 't') {
                            shift = (char) (shift + 26);
                            plaintext += shift;
                        } else {
                            plaintext += shift;
                        }
                    }
                } else {
                    plaintext += shift;
                }
            }

            System.out.println(ciphertext);

            // At this point, plaintext is the shifted ciphertext.
            System.out.println("distance " + distance);
            System.out.println(plaintext);
            System.out.println("Press enter to see the next option,"
                    + "type 'quit' to quit.");
            next = keyboard.nextLine().trim();
        }
        System.out.println("Final shift distance was " + distance + " places");
    }
}
导入java.io.File;
导入java.io.IOException;
导入java.util.Scanner;
公共类密码{
公共静态void main(字符串[]args){
//加密文本
字符串密文;
//键盘输入
扫描仪键盘=新扫描仪(System.in);
如果(args.length>0){
密文=”;
试一试{
扫描仪输入文件=新扫描仪(新文件(args[0]);
while(inputFile.hasNext())
ciphertext+=inputFile.nextLine();
}捕获(ioe异常ioe){
System.out.println(“未找到文件:+args[0]);
系统退出(-1);
}
}否则{
系统输出打印(“请输入文本-->”;
ciphertext=键盘.nextLine();
}
// -----------------------------------------------------------------
int distance=0;//密文应该移动多远
String next=”“;//查看后的用户输入
而(!next.equals(“退出”)){
字符串纯文本=”;
距离+=1;
for(int i=0;i'0'&移位<'A'){
移位=(字符)(移位+26);
纯文本+=移位;
}否则{
纯文本+=移位;
}
}
if(Character.isLowerCase(ciphertext.charAt(i))){
if(shift>'0'&&shift<'a'&&ciphertext.charAt(i)<'t'){
移位=(字符)(移位+26);
纯文本+=移位;
}否则{
纯文本+=移位;
}
}
}否则{
纯文本+=移位;
}
}
System.out.println(密文);
//此时,明文就是移位的密文。
System.out.println(“距离”+距离);
System.out.println(纯文本);
System.out.println(“按enter键查看下一个选项,”
+“键入'quit'退出。”);
next=keyboard.nextLine().trim();
}
System.out.println(“最终移位距离为“+距离+位置”);
}
}

您的方法中的转换是如何工作的?它利用了一个事实,即在Java中,
char
也可以被视为一个
int
,一个简单的数字

因此,你可以做这样的事情:

char c = 'A';                                 // Would print: A
int cAsValue = (int) c;                       // Would print: 65
int nextValue = cAsValue + 1;                 // Would print: 66
char nextValueAsCharacter = (char) nextValue; // Would print: B
甚至是:

int first = (int) 'A';                // Would print: 65
int second = (int) 'D';               // Would print: 68
int third = first + second;           // Would print: 133
char thirdAsCharacter = (char) third; // Would not print anything meaningful

好的,现在我们知道了如何将
char
解释为
int
,让我们分析一下为什么
65
表示字符
A
,为什么
133
没有任何意义

这里的关键字是UTF-16。Java中的字符在
UTF-16
中编码,并且有一些表格列出了该编码的所有字符及其特定的十进制数,如

以下是相关摘录:

这就回答了为什么
65
代表
A
以及为什么
133
毫无意义


某些移位后出现奇怪结果的原因是字母表只有26个符号

我想你会期望它重新开始,然后被
26
移位的
a
又是
a
。但不幸的是,您的代码不够智能,它只接受当前字符并向其添加移位,如下所示:

char current = 'a';
int shift = 26;

int currentAsInt = (int) current;        // Would print: 97
int shifted = currentAsInt + shift;      // Would print: 123
char currentAfterShift = (char) shifted; // Would print: {
将其与表中的相关部分进行比较:

因此,在
z
之后不再出现
a
,而是出现
{


所以,在谜团被解开之后,让我们现在谈谈如何修复它,并使您的代码更智能

您可以简单地检查边界,例如“如果它大于'z'的值或小于'a',然后将其重新返回到正确的范围”。我们可以通过使用
%
给出的模运算符来轻松完成此操作。它将一个数除以另一个数,并返回除法的剩余部分

以下是我们如何使用它:

char current = 'w';
int shift = 100;
int alphabetSize = 26; // Or alternatively ('z' - 'a')

int currentAsInt = (int) current;          // Would print: 119
int shiftInRange = shift % alphabetSize;   // Would print: 22
int shifted = currentAsInt + shiftInRange; // Would print: 141 (nothing meaningful)

// If exceeding the range then begin at 'a' again
int shiftCorrected = shifted;
if (shifted > 'z') {
    shiftCorrected -= alphabetSize; // Would print: 115
}

char currentAfterShift = (char) shiftCorrected; // Would print: s 
因此,我们不必按
100
移位,只需将相关部分移位,
22
。想象角色在整个字母表中进行三轮,因为
100/26~3.85
。在这些三轮之后,我们进行剩余的
0.85
轮,即
22
步rong>将
100
除以
26
后的余数
。这正是
%
操作符为我们所做的


在进行了
22
步之后,我们仍然可以超出界限,但最多可以超过一轮。我们通过减去字母表大小来纠正这一点。因此,我们不进行
22
步,而是进行模拟的
22-26=-4步“在字母表的末尾执行4个步骤,然后再次从'a'开始,最后执行18个步骤到's'。

方法中的转换是如何工作的?它利用了一个事实,即在Java中,
char
也可以被视为一个
int
,一个简单的数字