【问题标题】:Caesar Cipher Java凯撒密码 Java
【发布时间】:2015-05-02 21:03:31
【问题描述】:

我正在尝试使用 StringBuilder 制作凯撒密码,但我遇到了 2 个主要问题。一个是我的加密和解密不会相互抵消,另一个是当我使用 .isLetter() 函数时,它实际上会跳过很多字符,而不仅仅是忽略空格。谁能帮帮我?

import java.io.*;
import java.util.Scanner;

import javafx.scene.transform.ScaleBuilder;


public class FileUtilities
{
    static String tempE ; 
    static String tempD ;

    public static void main(String [] args)
    {

        try
        {

            File iFile = new File("BattlePlans.txt");
            File oFile=  new File("decodedBattlePlans.txt");

            Scanner input = new Scanner(iFile);
            PrintWriter fout = new PrintWriter(oFile);

            while(input.hasNextLine())
            {
                tempE = input.nextLine();
                //System.out.println(args[0]);
                //StringBuilder str = new StringBuilder(args[1]);

                //My encrypt funtion give me an indexoutofbounds error for some           reason and I don't know why do you see what I did wrong

                if(args[0].equals("encrypt"))
                {
                    fout.println(encrypt(tempE, Integer.parseInt(args[1])));

                }else if(args[0].equalsIgnoreCase("decrypt"))
                {
                    fout.println(decrypt(tempE, Integer.parseInt(args[1])));

                }


            }
            input.close();
            fout.close();
        }
        catch(FileNotFoundException e)
        {

        }
        // this is commented out becuase I couldn't figure out
        //how to make the InvalidCommand method or InvalidShift methods
        //and it was keeping it from running
        //do I even have to make my own, or is there something built in I can use?

        /*catch(InvalidCommand i)
        {
            System.out.println("Invalid command");
        }
        catch(InvalidShift s)
        {
            System.out.println("Invalid shift");
        }*/


    }

    public static String encrypt(String encrypt, int shift)
    {

        //first SB takes in the original text and second SB holds the changed txt
        StringBuilder str = new StringBuilder(encrypt);
        StringBuilder str2 = new StringBuilder();

        for(int i = 0; i < str.length(); i++ )
        {

            // I want to use a isLetter() if statement here to that it won't take out my space characters but when I did it made it print nothing so I deleted it
            char s = encrypt.charAt(i);

            //checks for capital and lowercase letter to see what the shift range is
            if(Character.isLetter(i))
            {
                if(s >= 'A' && s <= 'Z')
                {
                    //I went to the ILC to ask how to handle the shift and I could just add it to the end
                    //I was told that I couldn't and had to use another int and subtract the bottom of the range from the character at the index i
                    //the subtract the shift. It shifts the text to the left actually. is that okay?
                    int x = s - 'A' - shift;
                    x = x % 26;             
                    str2.append((char)(x + 'A'));

                    // add to str with .append

                }else if(s >= 'a' && s <= 'z')
                {
                    int z = s - 'a' - shift;
                    z = z % 26;
                    str2.append((char)(z + 'a'));
                }

            }
        }

        return str2.toString();
    }
    public static String decrypt(String decrypt, int shift)
    {
        //first SB takes in the original text and second SB holds the changed txt
        StringBuilder str = new StringBuilder(decrypt);
        StringBuilder str2 = new StringBuilder();
        for(int i = 0; i < decrypt.length(); i++)
        {
            char s = decrypt.charAt(i);

            //same if statement for encrypt would go here to so that it would keep the whitespaces
            if(Character.isLetter(i))
            {
                if(s >= 'A' && s <= 'Z')
                {
                    //I went to the ILC to ask how to handle the shift and I could just add it to the end
                    //I was told that I couldn't and had to use another int and subtract the bottom of the range from the character at the index i
                    //the subtract the shift. It shifts the text to the left actually. is that okay?
                    int x = s + 'A' + shift;
                    if(x < 0)
                        x = x + 26;
                    str2.append((char)(x + 'A'));

                    // add to str with .append

                }else if(s >= 'a' && s <= 'z')
                {
                    int z = s + 'a' + shift;

                    if(z < 0)
                        z = z + 26;
                    z = z % 26;
                    str2.append((char)(z + 'a'));

                }

            }
        }

        //decrypt is encrypt backwards
        return str2.toString();
    }
}

【问题讨论】:

  • isLetter 函数识别字母而非非空白字符。查看isWhitespace 函数。
  • 是的,但是我想检查它是否是一个字母,然后在if语句中做代码。

标签: java


【解决方案1】:

一些提示:

  1. 测试Character.isLetter(s),而不是Character.isLetter(i)。目前,您正在测试符号的索引,而不是符号本身。

  2. 确保您正在服用的mod 26,在计算x = x % 26 之前将+26 添加到x

  3. 为什么有两个独立的 encryptdecrypt 方法?消除其中一个。

  4. isLetter 是不必要的,你还是检查&gt;= 'A'&lt;= 'Z'

【讨论】:

  • 如果我删除我的解密方法,我将如何解密这些东西?
  • 通过简单地用负移位加密它。你可以为它提供一个方便的方法,添加一个减号,但你当然不需要两个实现。