In: Computer Science
Hello! I'm trying to write a code that will either encrypt/decrypt a message from an inputed text. I'm having the absolute hardest time getting stared and figuring out how to identify in the code if the input needs to be encrypted/decrypted and identifying the string to encrypt/decrypt with. These are the instructions:
Objectives
Program Description
Gaius Julius Caesar encoded his battle messages so that the opponent could not read them should they intercept them. The cipher required that both Caesar and the recipient knew the key to the cipher.
You are to write a program that reads in a message from a text file, encodes the message with a Caesar cipher, and then outputs the message to another file. Your program should also be able to read in an encoded message and decode it.
Define What this program must do. We did this in class. Check your class notes!
Outline How this program will accomplish the task. Your solution should be modularized.
Specifications
Input
The program should read, in order, command line arguments.
- The filename of the text file to open
- The cipher key for encryption/decryption
- A digit: 1 to encode or 2 to decode
*Using an IDE, look for "Run configurations" to set arguments. The IDE arguments needed are only the filename, cipher key, and encode/decode digit. You don't need the "java Cipher" portion that would be required if truly running from the command line.
Example of full command line input to encrypt:
java Cipher messageFile secretword 1 The result is a new encoded file called "messageFile.coded"
Example of full command line input to decrypt:
java Cipher messageFile.coded secretword 2 The result is a new decoded file called "messageFile.decoded"
Note that the decoded message in "messgeFile.decoded" should be identical to the original file "messageFile"
Errors and Exception handling
Encryption and Decryption
To encrypt a message, each letter in the message is shifted right by a number corresponding to the distance of the cipher key letter from the first letter in the alphabet. The cipher key is reused over and over until the message is encrypted. Punctuation and spaces are not encrypted but still appear in the encoded message. Uppercase should be converted to lowercase. Letters "wrap" around from 'z' to 'a'.
Message: the ships sail
Cipher key: swiftly
Output: ldm lsgho xttj wb wluf
Message letter | Alphabet value | Cipher letter | Alphabet Value | Add Values / Wrap for Offset | 'a' + Offset = Result |
---|---|---|---|---|---|
t | 19 | s | 18 | 37 % 26 = 11 | l |
h | 7 | w | 22 | 29 % 26 = 3 | d |
e | 4 | i | 8 | 12 % 26 = 12 | m |
f | none | ||||
s | 18 | t | 19 | 37 % 26 = 11 | l |
h | 7 | l | 11 | 18 % 26 = 18 | s |
i | 8 | y | 24 | 32 % 26 = 6 | g |
p | 15 | s | 18 | 33 % 26 = 7 | h |
s | 18 | w | 22 | 40 % 26 = 14 | o |
i | none | ||||
s | 18 | f | 5 | 23 % 26 = 23 | x |
a | 0 | t | 19 | 19 % 26 = 19 | t |
i | 8 | l | 11 | 19 % 26 = 19 | t |
l | 11 | y | 24 | 9 % 26 = 9 | j |
Other examples:
Message: the ships sail at dawn
Cipher key: secretword
Output: llg waedj kekc tp udor
Message: the ships sail at dawn
Cipher key: aaa
Output: the ships sail at dawn
Output
Helper Methods
You will want to add methods to shift up and down.
And this is the template provided:
/*
* Fix me
*/
import java.util.Scanner;
import java.io.PrintWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Cipher {
public static final int NUM_LETTERS = 26;
public static final int ENCODE = 1;
public static final int DECODE = 2;
public static void main(String[] args) /* FIX ME */ {
// letters
String alphabet = "abcdefghijklmnopqrstuvwxyz";
// Check args length, if error, print usage message and exit
if (args.length...
// Extract input args to variables
String inputFilename =
String key =
int action =
String outputFilename =
getOutputFilename(inputFilename, action);
Scanner input =
openInput(inputFilename);
PrintWriter output =
openOutput(outputFilename);
// Read in data and output to file
// Convert all letters to lowercase for output
// Close streams
}
/**
* Open input for reading
*
* @param filename
* @return Scanner
* @throws FileNotFoundException
*/
/**
* Open output for writing
*
* @param filename
* @return PrintWriter
* @throws FileNotFoundException
*/
/**
* Encode letter by some offset d
*
* @param c input character
* @param offset amount to shift character value
* @return char encoded character
*/
public static char shiftUpByK(char c, int distance)
{
if ('a' <= c && c <=
'z')
return (char)
('a' + (c - 'a' + distance) % NUM_LETTERS);
if ('A' <= c && c <=
'Z')
return (char)
('A' + (c - 'A' + distance) % NUM_LETTERS);
return c; // don't encrypt if not
an ic character
}
/**
* Decode letter by some offset d
*
* @param c input character
* @param offset amount to shift character value
* @return char decoded character
*/
/**
* Changes file extension to ".coded" or
".decoded"
*
* @param filename
* @return String new filename or null if action is
illegal
*/
public String getInfo() {
return "Program 3, Student's name
here";
}
}
If someone could please help and use the template to code this in JAVA in the next couple of days it would be greatly appreciated, thank you!!!
Hi, I have written an implementation for the above scenario with appropriate comments wherever necessary for better understanding.
Note : in the below implementation input and output are as follows:
INPUT : java Cipher messageFile.decoded secretword 1 ( to encode )
OUTPUT : java Cipher messageFile.coded secretword 2 ( to dencode )
In the below implementation
key.charAt(i % key.length()) - 'a') gives us the next character of the key that is to be used to shift the character.
basically, we have to use mod operator that limits the integer values till key length.
Other functions should be straightforward to understand. If you find difficulty understanding anything, please drop a comment.
Following is the implementation:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class Cipher {
public static final int NUM_LETTERS = 26;
public static final int ENCODE = 1;
public static final int DECODE = 2;
public static void main(String[] args) {
// Check args length, if error, print usage message and exit
if (args.length < 3) {
System.out.println("Invalid arguments");
System.exit(0);
}
// Extract input args to variables
String inputFilename = args[0];
String key = args[1];
int action = Integer.parseInt(args[2]);
// check if action is valid
if(action!=1 || action!=2) {
System.out.println("Option #"+action+" is not valid");
System.exit(0);
}
// get output filename
String outputFilename = getOutputFilename(inputFilename, action);
// set input and output
Scanner input = openInput(inputFilename);
PrintWriter output = openOutput(outputFilename);
// Read in data and output to file
while (input.hasNextLine()) {
// read next line
String line = input.nextLine();
String result = "";
// if action is encode
if (action == ENCODE) {
result = encodeInput(line, key);
} else {
result = decodeInput(line, key);
}
System.out.println(result);
// write to file
output.write(result);
}
// Close streams
input.close();
output.close();
}
/**
* Encode letter by some offset d
*
* @param c input character
* @param offset amount to shift character value
* @return char encoded character
*/
public static char shiftUpByK(char c, int distance) {
if ('a' <= c && c <= 'z')
return (char) ('a' + (c - 'a' + distance) % NUM_LETTERS);
if ('A' <= c && c <= 'Z')
return (char) ('A' + (c - 'A' + distance) % NUM_LETTERS);
return c; // don't encrypt if not an ic character
}
/**
* Decode letter by some offset d
*
* @param c input character
* @param offset amount to shift character value
* @return char decoded character
*/
public static char shiftDownByK(char c, int distance) {
if ('a' <= c && c <= 'z')
return (char) ('a' + (c - 'a' - distance + 26) % NUM_LETTERS);
if ('A' <= c && c <= 'Z')
return (char) ('A' + (c - 'A' - distance + 26) % NUM_LETTERS);
return c; // don't encrypt if not an ic character
}
/**
* Open input for reading
*
* @param filename
* @return scanner object of input file to read the file
* @throws FileNotFoundException
*/
public static Scanner openInput(String inputFile) {
File file = new File(inputFile);
// Creating Scanner instnace to read File in Java
try {
return new Scanner(file);
} catch (FileNotFoundException e) {
System.out.println("invalid input file");
e.printStackTrace();
}
return null;
}
/**
* Open output for writing
*
* @param filename
* @return PrintWriter
* @throws FileNotFoundException
*/
public static PrintWriter openOutput(String outputFile) {
File file = new File(outputFile);
try {
return new PrintWriter(file);
} catch (FileNotFoundException e) {
System.out.println("invalid output filename");
e.printStackTrace();
}
return null;
}
/**
* Changes file extension to ".coded" or ".decoded"
*
* @param filename
* @return String new filename or null if action is illegal
*/
public static String getOutputFilename(String input, int action) {
// if file extension is not provided
if (!input.contains(".")) {
System.out.println("invalid input file passed");
return null;
} else {
// get the file name
String fileName = input.split("\\.")[0];
if (action == ENCODE)
return fileName + ".coded";
else
return fileName + ".decoded";
}
}
// encode the text input using a key
public static String encodeInput(String input, String key) {
// initial result
String result = "";
for (int i = 0; i < input.length(); i++) {
// to encode shift up by k
char encodedLetter = shiftUpByK(input.charAt(i), key.charAt(i % key.length()) - 'a');
// append the encoded character to the result
result += encodedLetter;
}
// return result
return result;
}
// decode the encoded input using a key
public static String decodeInput(String input, String key) {
// initial result
String result = "";
// loop throuh the input
for (int i = 0; i < input.length(); i++) {
// to decode shift down by k
char encodedLetter = shiftDownByK(input.charAt(i), key.charAt(i % key.length()) - 'a');
// append the decoded character to the result
result += encodedLetter;
}
// return result
return result;
}
}