用Java创建一个简单的Caeser Cipher

时间:2016-09-21 19:02:18

标签: java

我需要创建一个密码,该密码将从用户获取一个字符串,以及一个将改变字符串中字符的移位号,并将其移动到用户输入的数字。这是我的一个课程的项目,我被困在我做错了什么。我们必须使用数组并且必须使用在开头声明的常量。基本上我们可以使用我的代码中已有的东西。我还没有完成decrypt部分。但该方法应该只将encrypted代码还原为原始代码。

import java.util.Scanner;


public class CaesarCipher {

public static final String UPPER_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz";
public static final String DIGITS = "0123456789";

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

  String cipherText = "";

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

    char c = plainText.charAt(i); 

    int newShift = UPPER_ALPHABET.indexOf(c) + shift;

    if (newShift < 0) {
      newShift += 26;
    } 
    else if (newShift > 25) {
      int remainder = newShift % 25;
    } 
    else if (newShift >= 0 && newShift < 26) {  
      newShift = newShift;
    }         
    newShift = UPPER_ALPHABET.indexOf(c) + shift;
    cipherText += UPPER_ALPHABET.charAt(newShift);
  }   
  for (int i = 0; i < plainText.length(); i++) {

    char c = plainText.charAt(i); 

    int newShift = LOWER_ALPHABET.indexOf(c) + shift;

    if (newShift < 0) {
      newShift += 26;
    } 
    else if (newShift > 25) {
      int remainder = newShift % 25;
    } 
    else if (newShift >= 0 && newShift < 26) {  
      newShift = newShift;
    }         
    newShift = LOWER_ALPHABET.indexOf(c) + shift;
    cipherText += LOWER_ALPHABET.charAt(newShift);
  }    
  for (int i = 0; i < plainText.length(); i++) {

    char c = plainText.charAt(i); 

    int newShift = DIGITS.indexOf(c) + shift;

    if (newShift < 0) {
      newShift += 26;
    } 
    else if (newShift > 25) {
      int remainder = newShift % 25;
    } 
    else if (newShift >= 0 && newShift < 26) {  
      newShift = newShift;
    }         
    newShift = DIGITS.indexOf(c) + shift;
    cipherText += DIGITS.charAt(newShift);
  } 
  //System.out.println(cipherText);
  return cipherText;
}

//public static String decrypt ( String cipherText , int shift ) {   
//  System.out.println(cipherText);
//  return cipherText;
//}

public static void main(String[] args) {   

  Scanner input = new Scanner(System.in);

  System.out.println("Enter the String for Encryption: ");
  String plainText = input.next();


  System.out.println("Enter a positive interger between 0 and 25 to create our CeasarCipher");
  int shift = input.nextInt();

  if (shift < 0 || shift > 25) {
    System.out.println("Don't be a jerk ... follow directions!");
    System.exit(0);
  }
  else {
    encrypt(plainText, shift);     
    }
  } 
}

2 个答案:

答案 0 :(得分:3)

你的代码以错误的方式解决了这个问题。您将每个字符视为大写,然后是小写,然后是数字,为每个字符添加三次转换来增加密文。在移动它之前,您不必费心测试main()的结果以查看它是否在字符集中。你没有正确处理标点符号(传递它)。您的模块化算术在几个地方关闭,而import java.util.Scanner; public class CaesarCipher { public static final String UPPER_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static final String LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz"; public static final String DIGITS = "0123456789"; public static String encrypt (String plainText, int shift) { String cipherText = ""; for (int i = 0; i < plainText.length(); i++) { char c = plainText.charAt(i); String alphabet = null; if (UPPER_ALPHABET.indexOf(c) > -1) { alphabet = UPPER_ALPHABET; } else if (LOWER_ALPHABET.indexOf(c) > -1) { alphabet = LOWER_ALPHABET; } else if (DIGITS.indexOf(c) > -1) { alphabet = DIGITS; } if (alphabet != null) { int length = alphabet.length(); c += shift; while (c > alphabet.charAt(length - 1)) { c -= length; } } cipherText += c; } return cipherText; } public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("Enter the String for Encryption: "); String plainText = input.nextLine(); System.out.print("Enter a positive integer between 0 and 25 to create our CeasarCipher: "); int shift = input.nextInt(); if (shift < 0 || shift > 25) { System.out.println("Don't be a jerk ... follow directions!"); System.exit(0); } System.out.println(encrypt(plainText, shift)); } } 例程无法正确读取文本行。

问题比你做的更简单。在提出的约束条件下工作,这里是重写加密文本的代码:

decrypt

encrypt方法可以通过对//$content = utf8_decode($content); //Converting to UTF16LE with BOM [chr(255) . chr(254)] for MAC version $content = chr(255) . chr(254) . mb_convert_encoding($content, 'UTF-16LE', 'UTF-8'); file_put_contents($file, $content); 方法的微不足道的修改来推导出来。

答案 1 :(得分:1)

我同意cdlane的回答,但也有几点要补充。关于重构的三个一般事项:

  • 没有&#34;如果&#34;无效的语句(例如将newShift分配给自己的语句)
  • 使用DRY校长(不要重复自己)。如果你连续几次做几乎相同的程序,你几乎肯定要么算法错误或需要重构。在这种情况下,你可以测试一下使用哪个字母表&#34;在前面&#34;就像他的例子中的cdlane一样。
  • 仅创建您打算使用的值。例如,您永远不会使用值int remainder = newShift % 25;,这可能表示错误或不完整的代码部分(如果您打算使用它但忘记了)或需要重构/清理代码。

这是一个可能的实现(用C#而不是Java编写,但没有太大的区别)。我还没有像我想的那样彻底地测试它,它只适用于小写字母,但它也可以修改为处理其他输入类型:

public string CaesarCypher(string toEncode, int shift)
    {
        var sb = new StringBuilder();

        foreach (char c in toEncode)
        {
            // Convert the character to its ASCII equivalent
            int curr = c;
            // Num could be either positive or negative
            curr += shift;

            /* Below we handle the case where there's a "wrap-around." Examples:
             * - Shift of 27 is equivalent to a shift of 1, for example
             * - Shifting "z" by 1 wraps it around to "a"
             */

            // If they wrapped around by shifting to the right (num is positive).
            // We could do something similar to this with Modular arithmetic too
            while (curr > 122)
                curr -= 26;
            // If they wrapped around by shifting to the left (num is negative).
            while (curr < 97)
                curr += 26;

            sb.Append((char)curr);
        }

        return sb.ToString();
    }

以下是我在其上运行的测试:

Console.WriteLine(cls.CaesarCypher("z", 2)); // b

            Console.WriteLine(cls.CaesarCypher("a", 1)); // b
            Console.WriteLine(cls.CaesarCypher("a", 2)); // c
            Console.WriteLine(cls.CaesarCypher("a", 3)); // d
            Console.WriteLine(cls.CaesarCypher("a", 4)); // e
            Console.WriteLine(cls.CaesarCypher("a", 5)); // f
            Console.WriteLine(cls.CaesarCypher("a", 6)); // g
            Console.WriteLine(cls.CaesarCypher("a", 7)); // h
            Console.WriteLine(cls.CaesarCypher("a", 24)); // y
            Console.WriteLine(cls.CaesarCypher("a", 25)); // z
            Console.WriteLine(cls.CaesarCypher("a", 26)); // a (shift of 26 is equivalent to no shift)
            Console.WriteLine(cls.CaesarCypher("a", 27)); // b (shift of 27 is equivalent to a shift of 1)