代做Java – 这是一个基于java的编程练习题目
Java Programming Project: Clype 1
In this multi-part programming project, you will design and implement Clype (short for Clarkson Skype), an instant messaging application akin to Skype that runs as a standalone application. [Incidentally, the word clype in Scottish slang stands for a person who tells tales: https://www.collinsdictionary.com/us/dictionary/english/clype)]. In Clype 1.0 (the first version of Clype), you will implement a single-session instant messaging and file-sharing terminal application in four individual assignments. Multiple clients can communicate with each other in the single session.
assignment 2 : Input-Output (I/O)
Now that you have written code for the basic structure of the class hierarchy, you will now start populating the un-filled method blocks to perform some real tasks. In this assignment, you will address input-output (I/O), both file and standard I/O.
In this assignment, you will perform **secure I/O. ** Given a message in MessageClypeData or file contents read from a file in FileClypeData, you will encrypt the message or file contents into a secure string using a key . To output the contents of the message or file contents, you will need to have the same key to decrypt the secure string. The objective of doing this is that as a client, when you send your message/file contents to the server, and the server distributes your message/file contents to your clients, only authorized clients must be able to read your message or file. These authorized clients will have the same key as you.
We will use the Vignre cipher to encode and decode our file. For more information about the cipher, read the following Wikipedia article: https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher The article should provide you a direction on implementing the cipher. The cipher uses a key that is known by both the encrypting method and decrypting method. The cipher is a more complex version of the Caesar cipher:https://en.wikipedia.org/wiki/Caesar_cipher The Caesar cipher is a simple substitution cipher, where during encrypting each letter is replaced in a circular fashion by a letter N steps away from it, for instance, if N = 5, A is replaced by E, B by F, C, by G and so on. V is shifted to Z, so W is circularly shifted back to A, X is shifted to B, Y to C and Z to D. You then decrypt by going backwards, and the key is the value of N.
The Caesar cipher can actually be broken pretty easily even without knowing N (think about how!), so the Vignere cipher goes a step further by using a key of several letters. For instance, to encrypt BRAVE NEW WORLD, if I use the key TIME, then the encrypting is done as follows:
- Repeat the key TIME for as many characters there are in BRAVE NEW WORLD: String: BRAVE NEW WORLD Repeated Key: TIMET IME TIMET
- Shift each character in the string by the alphabet location of the letter in the repeated key, i.e.: T is the 20th letter, so shift B (position 1 ) by 20- 1 to U (position 2 0 ) I is the 9th letter, so shift R (position 17) by 9- 1 to Z (position 25) M is the 13th letter, so shift A (position 0 )by 13-1 to M (position 1 2 ) E is the 5th letter, so shift V (position 21) by 5- 1 to Z (position 25) . . . The entire encryption for the string ends up being UZMZX VQA PWDPW. Be sure to handle circular shift using modulo arithmetic, e.g., if you calculate the position to be 28, then it should circularly shift back to 3, i.e., to C.
Decryption is then done by going backwards, i.e., by subtracting the shifts of the letters TIME repeated across the encrypted string. For your assignment, you can leave all non-alphabet characters unchanged, including spaces. However, you must preserve case (upper-case letters should remain upper-case in the encryption, and same for lower-case).
Note that while this is a simple encryption approach, it is not without flaws. As you do the assignment, think about the ways in which this encryption could be vulnerable. You are not required to implement a more complex encryption scheme, however, if you would like to know more, do consider taking Cryptography with Dr. Tamon (and if you are feeling adventurous, you can explore harder encryption schemes for yourself!)
You will write the following code to implement secure I/O:
1. New methods in ClypeData for encryption and decryption. You will add the following new methods encrypt and decrypt in ClypeData:
protected String encrypt( String inputStringToEncrypt, String key ) This method takes in an input string to encrypt using a key, and outputs the encrypted string. It is protected so that only itself and its subclasses can use the method. For this method, implement the Vignre cipher to perform the encryption with a key provided as input. You can choose any key of any length, but do read the Wikipedia article for a discussion on what key lengths are good to use. It is possible to break even the Vignre cipher without a key if the key satisfies certain ripe conditions for breaking. For any encryption in the rest of the assignment, you should call this method.
protected String decrypt( String inputStringToDecrypt, String key ) This method takes in an input string to decrypt using a key, and outputs the decrypted string. It is protected so that only itself and its subclasses can use the method. For this method, implement the backwards decryption of the Vignre cipher to perform the decryption with key provided as input. For any decryption in the rest of the assignment, you should call this method.
2. Add new constructor to MessageClypeData that takes in a key. Implement the following constructor in MessageClypeData: MessageClypeData( String userName, String message, String key, int type ). This constructor should immediately encrypt the message using the key, i.e., this.message should be an encrypted message. DO NOT SAVE THE KEY AS AN INSTANCE VARIABLE (why?). 3. Have abstract overloaded method getData in ClypeData with implementation in MessageClypeData and FileClypeData.
You already have the method getData() in ClypeData that returns a String, is abstract, and is implemented in MessageClypeData and FileClypeData. Now include an overloaded method getData( String key ) that is abstract in ClypeData, and that is meant to return the original data in an encrypted string.
In MessageClypeData, override getData( String key ) to decrypt the string in message and return the decrypted string.
In FileClypeData, override getData( String key ) to decrypt the string in fileContents and return the decrypted string.
4 . Implement methods readFileContents and writeFileContents in FileClypeData, and have overloaded methods for both. In assignment 1, you wrote the signature for two methods, readFileContents() and writeFileContents. Here you will not only implement them, you will also overload them to take a key for secure file I/O.
public void readFileContents() throws IOException: This method takes in no arguments, and does non-secure file reads. For this method, you will open the file pointed to by the instance variable fileName, read the contents of the file to the instance variable fileContents, and close the file. You must catch all relevant exceptions, and print informative messages to standard error. Note: you should catch a separate exception for file not found. The method must throw an IOException.
public void readFileContents(String key) throws IOException: This overloaded method takes in one argument, and does secure file reads. This method is not present in Assignment 1. For this method, you will open the file pointed to by the instance variable fileName, read the contents of the file, encrypt the contents to the instance variable fileContents using key, and close the file. You must catch all relevant exceptions, and print informative messages to standard error. Note: you should catch a separate exception for file not found. The method must throw an IOException.
public void writeFileContents(): This method takes in no arguments, and does non-secure file writes. For this method, you will open the file pointed to by the instance variable fileName, write the contents of the instance variable fileContents to the file, and close the file. You must catch all relevant exceptions, and print informative messages to standard error.
public void writeFileContents(String key): This method takes in no arguments, and does secure file writes. For this method, you will open the file pointed to by the instance variable fileName, decrypt the contents of the instance variable fileContents and write them to the file, and close the file. You must catch all relevant exceptions, and print informative messages to standard error.
Note that if you have common functionality between readFileContents() and readFileContents(String key), you may want to consider implementing a private method inside FileClypeData that contains the common functionality. You may want to consider the same for writeFileContents() and writeFileContents(String key).
**5 . Set up the constants 0, 1, 2, and ** The variable type represents the kind of data exchanged between the client and the server. It is meant to enable the server to provide the client with targeted service. The variable type can take on the following values: 0: give a listing of all users connected to this session 1: log out, i.e., close this clients connection 2: send a file 3: send a message ClypeData objects of type 0, 1, and 3, will get instantiated as MessageClypeData. ClypeData objects of type 2 will get instantiated as FileClypeData. Assignment 1 was changed so that you did not need to implement these values as constants. If you have not already done so, implement these values as constants in ClypeData.
6 . Implement the methods start, readClientData, and printData in ClypeClient.
In this assignment, you will begin the implementation of ClypeClient. You will work on the server in the next assignment. Here, you will set up ClypeClient to get a message or a file from the user. In the final functionality, you will need to send this message or file to the server, but now, since we are not at that point yet, you will print the contents of the message or file to screen. To achieve this, you will first add a new instance variable, inFromStd declared as java.util.Scanner. You will then implement the following methods
readClientData(): This method takes in no arguments, and returns nothing. The method gets an input from the user through standard input, represented by inFromStd (which will be initialized in the method start() ). The method then initializes the ClypeData object dataToSendToServer based on the
following input: a) If the input is DONE close the connection (what variable can you use to do this?)
(b) If the input is SENDFILE
printData(): This method takes in no arguments, and returns nothing. It prints out the contents in the ClypeData object dataToReceiveFromServer to the client. The purpose of this method is to print out to all the clients the information sent by a particular user. This means that the printData() should output something meaningful to the client seeing the data. Think about what you should be printing out, and what methods you can use to help you.
start(): This method takes no arguments, and returns nothing. This method starts this clients communication with the server, i.e., it initiates all the fun stuff in this project! For now, your start() method will be simple, but you will evolve its functionality in future assignments. First initialize inFromStd to be a Scanner object that can be used in readClientData(). Then while the connection is still running, read the clients data using readClientData(), and then print the data using printData(). Since readClientData() reads into dataToSendToServer, and printData() writes from dataToReceiveFromServer, for now, set dataToReceiveFromServer to be the same as dataToSendToServer. Later, we will use them differently.
You should also have a key stored as a constant in ClypeClient that you will use for encryption and decryption. This key will be fed to the ClypeData objects you create in ClypeClient.
7. Change the constructors in ClypeClient when appropriate to throw an IllegalArgumentException for incorrect values of arguments. Look at the Javadoc for IllegalArgumentException to see how it is created. You must throw an
IllegalArgumentException if the user name is null, the host name is null, or the port is a number lesser than 1024 (we will see why port numbers should be 1024 or greater in the Networking lecture). You should determine which constructors need to throw the exception, and which do not.
At the end of this implementation, except the IllegalArgumentException, ClypeClient should be as follows. userName: String representing name of the client hostName: String representing name of the computer representing the server port: integer representing port number on server connected to closeConnection: boolean representing whether connection is closed or not dataToSendToServer: ClypeData object representing data sent to server dataToReceiveFromServer: ClypeData object representing data received from the server inFromStd: Scanner object representing standard input ClypeClient( userName, hostName, port ): constructor for username, host name, and port, connection should be set to be open (what should closeConnection be?), should set dataToSendToServer and dataToReceiveFromServer as null. ClypeClient( userName, hostName : constructor to set up port to default port number 7000, default port number should be set up as constant, this constructor should call another constructor. ClypeClient( userName ): constructor that sets host name to be localhost (i.e., the server and client programs run on the same computer) ClypeClient(): default constructor that sets anonymous user, should call another constructor start(): does not return anything, but starts the connection, reads data from the client, and prints the data out. readClientData(): reads the data from the client, does not return anything sendData(): sends data to server, does not return anything, for now it should have no code, just a declaration receiveData(): receives data from the server, does not return anything for now it should have no code, just a declaration printData(): prints the received data to standard output, getUserName(): returns the user name getHostName(): returns the host name getPort(): returns the port hashCode(): should be correctly overridden equals(): should be correctly overridden toString(): should be overridden to return a full description of the class with all instance variables
**Start soon! ** You have encryption and decryption algorithms to implement, a whole bunch of I/O to take care of, and exceptions to handle.
Modify your TestClypeData class to test the new methods in all data classes. Modify your TestClypeClient class to create a ClypeClient object and to start. For TestClypeClient, test all combinations of constructors and types (1, 2, and 3; 0 will not be tested here as it makes more sense when you have multiple clients). Your submission should contain an output from command line copied in for TestClypeClient. Your submission should also test the creation of FileClypeData using the attached file document.txt.
Submission: Your submission must consist of all .javacode. Your code must contain Javadoc comments, and your submission must also contain the Javadoc in a doc/ folder , any input test files you use (apart from document.txt) and a short report written in Word, OpenOffice or a similar document editor with the output from TestClypeClient.
Your submission must be uploaded to Moodle. You can submit in one of the two ways:
- A .zip file containing your entire code, Javadoc doc/ folder, and report. You must include your .java files stored under an src/ directory in the correct folder hierarchy that emanates on using packages. Please do not include supporting projectdirectories that arise when you use an IDE.
- A .txt file with a link to a location to an online repository version controlled using git such as BitBucket or GitHub with the above material, if you prefer to use such a version controlled repository. However, be forewarned that public repositories are liable to being stolen. If you create a private repository, make sure to add the TA, Miao Luo ([email protected]) to your repository users list.
Grading (out of 100, scaled down to 3 ): Task Grade allotment Encryption and decryption methods 15 Implementation of new constructor in MessageClypeData 5 Implementation of overloaded method getData in two MessageClypeData and FileClypeData classes
Implementation of overloaded methods readFileContents
and writeFileContents in FileClypeData
New functionality in ClypeClient 20
Correctly written and running TestClypeData 10
Correctly written and running TestClypeClient 15
Report with output from TestClypeClient 10
Javadoc comments, and Javadoc folder 5