Java代写:KIT101 Sentence Cipher

Introduction

这次作业非常基础,属于刚入门的Java编程。实现一个对Sentence的加解密算法,算法类似哈希,存在不可逆/无解的情况。

Quick overview

Task: Implement an encryption tool in Java that ‘hides’ messages within a larger piece of text and then later, given the positions of the letters, can reconstruct the original message.
Skills assessed:

  • declaration and manipulation of variables of primitive types and Strings
  • use of objects and methods in prewritten classes
  • branching control flow
  • looping control flow
  • writing wellformed and documented code

Background

For as long as people have been able to write they have tried to find ways to send messages secretly by hiding the message in some way. One way of encrypting a message is to hide it inside some other text. It works as follows: you and the intended message recipient both agree on a (large) piece of source text, such as a passage from a book, which you don’t share with anyone else. You then find a character position for each letter in your (much shorter) message within the larger piece of text, and send the list of positions. Here’s an example:

Source text (secret): The quick brown fox jumps over the lazy dog
Message to encrypt: bread
Encrypted message: 10 11 2 36 40

Of course, we could have taken alternative positions for ‘e’ (also found at positions 28 and 33) and ‘r’ (also at 29), but in this cipher we’ll always use the first occurrence of a letter.
If you look closely at the secret text above you’ll notice that it contains every letter in the English alphabet, which means we can encrypt any message we want (note we’ll be restricting ourselves to messages that do not contain spaces in this assignment). While this is likely to be true of any sufficiently long piece of text, what should we do if the message contains a letter not found in the secret text? In the absence of any valid substitute, let’s use 1 to indicate that it wasn’t found. Here’s an example of that:

Source text (secret): The quick brown fox jumps over
Message to encrypt: beak
Encrypted message: 10 2 1 8

Recovering the original message is simply a matter of looking up the character at each indicated position in the shared secret text, replacing any lost symbols with some agreed upon alternative, like ‘_’. A worked example:

Source text (secret): Shall I compare thee to a summer's day? Thou art more lovely and more temperate.
Received message: 0 1 2 1
14 0 11 14 2 13 14
Decrypted message: sha_espeare

Your Assignment

Your assignment will consist of a single class, with all code in the main() method. Call your class SentenceCipher (that is, the source code will be in a file called SentenceCipher.java). If you choose to use an IDE other than DrJava, ensure that your program is not defined in a package (there should be no package statement at the top of the file).
When your assignment is complete, a user running your program will be prompted to enter the shared ‘source’ text, then asked if they want to encrypt or decrypt a message. The source text may contain any mixture of characters, including punctuation and spaces. Before continuing, the source text must be converted to all lower case.
After receiving the source text from the user, they will be asked to choose one of two options:

  1. Encrypt a message
    • The user is prompted to enter a word to be encrypted (this word is converted to lower case).
    • The program finds the position in the source text of the first occurrence of each character from the word (or 1 if the character cannot be found) and creates a new String containing those positions, separated by spaces and ending with 2.
    • The program displays the list of positions, preceded by the text “Result: “.
    • On a separate line, the program outputs the amount of information loss. This should be preceded by “Information loss (%): “.
  2. Decrypt a message
    • The user is prompted to enter a list of positions, separated by spaces and ending with -2 (to indicate the end of the word).
    • As long as the next position is not 2, the program reconstructs the word one character at a time:
    • if the position is within the bounds of the source text then the character at that position is added to the word;
    • if the position is -1 then an underscore (_) is appended to the string, indicating an unrecoverable character; and
    • if the position is less than -1 or beyond the end of the source text then an exclamation mark (!) is appended to the word.
    • If there were any invalid positions (less than 1 or beyond the end of the source text) then the program should print a message indicating how many. The number should be followed by the text “invalid position(s)”. The message should not be displayed at all if there were no invalid positions.
    • The program outputs the recovered message, preceded by the text “Result:”
    • On a separate line, the program outputs the amount of information loss, On a separate line, the program outputs the amount of information loss, where the number of characters not found includes both positions of -1 and invalid positions. This should be preceded by “Information loss (%):”.

Note that both options finish by displaying the amount of information loss.
The three development and testing stages defined below will step you through creating a functioning cipher tool. You do not need to follow these suggested development stages, but if you do then a testing tool will be available that can run your partiallycompleted program with lots of different inputs and indicate when it works as expected and when it does not.

General guidance

Use the Scanner class (import it from the java.util package) to read the user’s input.
Your program will need to declare appropriate variables for holding the source text, user’s processing choice, and (for encryption) the word to be encrypted. Several other temporary variables will be needed.
Use constants to hold sensible default values and any special values that will be used repeatedly.
Use the method indexOf(c) to find the first position of the character c in a String. Use the method charAt(i) to find the character at position i in a String. For example, “moose”.charAt(0) is the character ‘m’.
Depending on when you start work on the assignment you may not yet have learned about loops (i.e., how to repeated execute a sequence of statements), which will be necessary to deal with entire words (for both encryption and decryption). But you can still do most of the assignment with only decision making statements such as if, if-else and switch. Until you learn how to write loops, make your program read the a word to be encrypted from the user and use charAt(0) to process just the first letter of their input, and then read just one integer position to decrypt a word later. The automated testing tool includes tests with one-letter words as well as longer strings.
Once you have learned how to write loops you can wrap your separate encryption and decryption code in suitable loops. For encryption you’ll then construct the encryptd message as a sequence of positions, separated by spaces. For decryption you’ll reconstruct the original word one character at a time as you process each position in turn.
Don’t be put off by the apparent complexity of the task. The development stages will take you through increasingly sophisticated programs in the same way that, when you become an expert, you will break down complex tasks into simpler ones.

Example Sessions

In these example sessions the user’s input is highlighted. All other text is produced by the program.

Sentence Cipher
Enter source text: The quick brown fox jumps over the lazy dog
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 1
Enter word to encrypt: bread
Result: 10 11 2 36 40 ‐2
Information loss (%): 0.0

Sentence Cipher
Enter source text: The quick brown fox jumps
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 1
Enter word to encrypt: tea
Result: 0 2 ‐1 ‐2
Information loss (%): 33.33333333333333

Sentence Cipher
Enter source text: The quick brown fox jumps
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 2
Enter positions (‐2 to end): 0 2 ‐1 ‐2
Result: te_
Information loss (%): 33.33333333333333

which is identical to if the user pressed Enter between each position (no change to your program will be necessary)

Sentence Cipher
Enter source text: The quick brown fox jumps
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 2
Enter positions (‐2 to end): 0
2
‐1
‐2
Result: te_
Information loss (%): 33.33333333333333

Sentence Cipher
Enter source text: Call me Ishmael.
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 1
Enter word to encrypt: CLAIM
Result: 0 2 1 8 5 ‐2
Information loss (%): 0.0

Sentence Cipher
Enter source text: WHY ARE YOU SHOUTING?
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 1
Enter word to encrypt: hurts
Result: 1 10 5 16 12 ‐2
Information loss (%): 0.0

Sentence Cipher
Enter source text: WHY ARE YOU SHOUTING?
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 2
Enter positions (‐2 to end): 1 10 5 16 12 ‐2
Result: hurts
Information loss (%): 0.0

Sentence Cipher
Enter source text: WHY ARE YOU SHOUTING?
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 2
Enter positions (‐2 to end): 1 10 50 56 ‐1 ‐2
There were 2 invalid position(s). Are you using the correct source text?
Result: hu!!_
Information loss (%): 60.0

Development Stages

The three assignment stages take you through developing: a program that can encrypt or decrypt a single character; a program that can encrypt and decrypt an entire word; and finally a program that can process an entire word and report on characters that could not be encrypted or decrypted and invalid positions given during decryption. Only the final stage directly contributes to your mark for this assignment.
Over the coming weeks you are encouraged to complete and test each of the following stages in turn. You are of course free to complete each stage more quickly or even to jump straight to the last one (if you believe you have a perfect solution).

Stage 1: Encrypt/decrypt one character

Suggested completion: Thursday 7 April (week 6)
In this stage of the assignment you will write a program that can encrypt or decrypt a message of just one character. Two example runs from your program at the end of this stage might look like:

Sentence Cipher Stage 1 Example
Enter source text: The quick brown fox jumps over the lazy dog
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 1
Enter word to encrypt: b
Result: 10 ‐2

Sentence Cipher Stage 1 Example
Enter source text: The quick brown fox jumps over the lazy dog
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 2
Enter positions (‐2 to end): 10 ‐2
Result: b

(Note that at this stage your program will probably not actually read the -2 during decryption, but it should still append it to the (encrypted) list of positions during encryption.)
Within this stage develop your program incrementally. First, make sure the source text is all lower case (there is a method of the String class that can help), then add suitable statements for reading the user’s choice of action, encryption or decryption. Second, implement the logic for dealing with encryption: read a single word from the user, convert it to lower case, and find its first character’s position in the source text; generate a String containing that position, a space and ending in -2.
Finally, add code to deal with decryption: read a single int from the user, find the character at that position (if it’s a valid position) and append that to a new empty String. Add some additional logic to deal with the special cases of -1 (not found, so output an underscore) and when the position is outside the bounds of the String (so output an exclamation mark).
Tip: For encryption and decryption, do all the processing with variables and then have a single System.out.println() statement to display the result, prefixed by “Result: “, as in the examples.
In this stage you will also need to write down an outline of how your final program will work (think of it as a more detailed version of the numbered steps above). It doesn’t have to look like code (or even pseudocode), but it must be a sequence of steps that it will perform.

Evaluation and testing

  1. Submit your program outline to the Assignment 1 Dropbox.
  2. Show your program’s code to your tutor to get their feedback on its coding style.
  3. Use the supplied testing tool to check your program (this will become available during Week 4). Note that all the checks it performs are ones you could do yourself; it merely automates the process and provides some feedback. It will also do tests that your program won’t pass yet (encrypting and decrypting words longer than one character, for instance), so only look at the first ones that use a single input character.

Stage 2: Process an entire string

In this stage you will modify your program so that it can process entire words, not just messages of a single character. The key change will be to place your existing encryption and decryption code insides loops (don’t forget to adjust the indentation to visually indicate that original single character processing code is nested inside each loop).
Think carefully about what kind of loop is best suited to each task. For encryption, you’ll have an entire String (one word) from the user and now must process each character in turn (so remember to change the argument you pass to charAt()). For decryption you will need to keep reading the next int from the user until you encounter the special sentinel value of 2. At the end of this stage your program will behave like this example:

Sentence Cipher Stage 2 Example
Enter source text: The quick brown fox jumps over...
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 1
Enter word to encrypt: Belize
Result: 10 2 ‐1 6 ‐1 2 ‐2

Sentence Cipher Stage 2 Example
Enter source text: The quick brown fox jumps over...
Select a cipher option:
1. Encrypt
2. Decrypt
Choice: 2
Enter positions (‐2 to end): 10 2 ‐1 6 ‐1 2 ‐2
Result: be_i_e

Evaluation and testing

  1. Show your work to your tutor to get their feedback on your program’s style.
  2. Use the supplied testing tool to run automated tests on your program. Your program should now pass all the single-character tests and all the whole word tests.

Stage 3: (final submission) Information loss and invalid positions

Time to finish the assignment by (1) counting and reporting on any invalid positions entered by the user during decryption and (2) reporting the amount of information loss, which is the percentage of message characters that couldn’t be found during encryption or couldn’t be retrieved during decryption because their position was not within the bounds of the source text. At the end of this stage you will have a complete program that will behave like the examples above. The information loss must be prefixed by the string “Information loss (%): “ so that the automated testing tool can identify it. If the message about invalid characters includes the text “ invalid position” after the number then the testing tool should identify the value.

Evaluation and testing prior to submission

Use the supplied testing tool to run automated tests on your program. The later tests also look for the number of invalid characters and information loss and will indicate if either is not found (when expected) or appears incorrect.