Top Secret

From CompSciWiki
Jump to: navigation, search

Back to the Program-A-Day homepage

Problem

You are a software developer for CSIS (Canadian Security Inteligence Service) and you've been sent a secret message, but all of the software at your station has been deleted! However, this message is very important and must be decoded right away. That's where you come in. You will write a program that decodes the message, verifies the authenticity, then prints out the mission directive.

First, the message is in a secret code. Every character is represented by a different character. The following arrays show the relationship. The first one is our alphabet, the second is the secret one.

char [] array1 = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','.','!',' '};
char [] array2 = {'l','x','g','r','j','w','!','i','q','a','t','z','.','s','y','k','e','o',' ','p','d','c','h','n','v','u','f','b','m'};




Once you've decoded the message, you'll have to verify it. Every other character, starting with the first character, if put together, will form a palindrome. You must write two methods: one that will form the palindrome out of the message, the other method to make sure that it is indeed a palindrome.

Once you've verified that, you'll need to get the mission instruction out of the message. It is formed by taking every other letter starting with the second character of the decoded message. (I suggest making your method that takes every other character work for both palindrome and instruction)

There is one final verification needed. The instruction must start with the phrase "top secret". If not, it's a fake! After you've determined that the instruction is the real deal, you have to print out just the mission instruction. (Use substring to print out the message after the "top secret" part)

 

Problem Solving and Programming Examples

Wiki bench01.jpg

Solution

When you start working on your program, don't forget to copy in those two char arrays and secret message.

We'll start this program by first deciding what methods we will need (apart from main), and what the signatures of those methods will be. This is an important step (especially during the exam) because it will prevent an unnecessary amount of erasing later on. From the problem stated above, we realise we need 4 methods. The first is to decode the message, and this one will have to be passed the secret message and the two char arrays. It will be returning the decoded message as a String. The second method is to take every other character, and combine them into a new String, which will be returned. It needs to be passed the String to perform this on, and we will be passing it an integer value. (The reason for this will be mentioned later on) The third method is to check the string produced by every even character to see if it's a palindrome. This will be passed the string to be checked, and will return a boolean. The fourth and last method is to check the string produced by every odd character to make sure it starts with the words "top secret". It too will be passed the string to check and the string containing the key to look for (the words "top secret"), and return a boolean.


Now that we've decided that, let's get to programming. First, I will make three calls from within main to get started. Note the integer value in the last two method calls. That's because in the "everyOther" method I use modulus to check for either odd or even numbered characters. You'll see the code for this in a bit, but it allows us to re-use a method for performing similar operations.

 String result = decode(secretMessage, array1, array2);
	String palindrome = everyOther(result,0);
	String message = everyOther(result,1); 


Now we should code in our check for a palindrome with a simple if-else statement. The else should print out an error message, and will look something like this,

 if(checkPalindrome(palindrome))
	{
	}
	else
		System.out.println("There was no palindrome.  This message is a fake!"); 


And within the "if" part, we will need to check the string made from all the odd numbered characters for the "top secret" string. If there is no match, we print out an error message. It it is a match, we will print out what the mission instruction is. (making sure we use substring to remove the "top secret" part out of the message) This gives us the following.

 if(checkSecrecy(message, start))
	{
		System.out.print("Your secret mission is: ");
		System.out.println(message.substring(start.length()+1,message.length()));
	}
	else
		System.out.println("There was no \"top secret\".  This message is a fake!"); 


And that is it for our main method. Now we will write code for our first method, the "decode" method. As mentioned before, it is passed a String and two char arrays, and returns a String. Within that method we'll declare and initialise our return variable right aways. Now we have:

 public static String decode(String message, char [] array1, char [] array2)
	{
		String result = "";

		return result;
	} 


When coding, I always make sure to include the return statement as well, but you won't always be able to do this when writing an exam. Now for decoding. We will be using two for loops. The outside loop is for iterating through every character in the string we need to decode, the inside loop is for iterating through every character in the second char array (secret code array). As for the decoding, we will be comparing the character in the string to characters in the second char array, and when we find a match, we take the subscript ("j") and take the character at that spot from the first array (english language array). We then append this character to our return string. This gives us:

 for(int i = 0; i < message.length(); i++)
	{
		for(int j = 0; j < array2.length; j++)
		{
			if(message.charAt(i) == array2[j])
				result += array1[j];
		}
	} 


And our decoding is done. Now for getting every other character out of this string. We decided earlier that we will pass it a string and an integer, and will be returning a String. So our method will look like this: (including return variable and return statement)

 public static String everyOther(String str, int num)
	{
		String result = "";

		return result;
	} 


Now we'll use a for loop for iterating through the string. As I'm sure you've encountered before already, when checking for even or odd numbers, using modulus (%) is easiest. And that's also where that integer we passed in is being used. We'll check for odd or even by "modding" i by 2, and comparring it to the passed integer. If i is equal to 0, it's even, otherwise, it's odd. We'll build our string accordingly, and return it. Here is an example of the loop with if statement.

 for(int i = 0; i < str.length(); i++)
	{
		if(i % 2 == num)
			result += str.charAt(i);
	} 


Now for checking the palindrome. The method just needs a string, and will pass back a boolean variable. We'll initialise the boolean variable to "true", since we will change it to "false" if at any point we notice the string is not a palindrome. We'll also write in the for loop right aways as well. The length of the loop is a bit different, since we just need to check half of the string. (The last half should be the same as the first half, only in reverse) So after cutting the length in half, our method so far will look like:

 public static boolean checkPalindrome(String str)
	{
		boolean result = true;

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

		return result;
	} 


We'll check each character at position i against each character at position str.length() - i - 1. We have to subtract 1 because just using str.length() - i will give us an error message. (It goes past the length of the string since we start counting from 0) If those two characters don't match, we change our return boolean to "false".

 if(str.charAt(i) != str.charAt(str.length() - 1 - i))
		result = false; 


For the last method, we need to check for "top secret". We need to pass this method both the string to check in (the message), and the string to look for ("top secret"). This method will be returning a boolean. We'll initialise our return boolean to "false", since we'll be turning it to "true" if the message contains the word we're looking for. You may have noticed that our boolean initialisations are not the same. One must give consideration as to what to initialise a boolean to. In practise, a developer wants to "switch" a boolean as little as possible in code. While it doesn't affect the computer or how it handles your program, it makes for more readable code, and gives it a cleaner look. (In the case of this method, I opted to go from "false" to "true" so I could avoid using the "!" symbol at the beginning of a long if check)

 public static boolean checkSecrecy(String message, String start)
	{
		boolean result = false;

		return result;      
	} 


And the actual check itself is quite simple. We'll be using substring again to pull out the beginning of the message, of a length equal to the second strings length. Then we check the two against each other, and change our return variable to "true" if they match.

 if(message.substring(0,start.length()).equals(start))
		result = true; 


Our program is now complete. I will leave it to you to write the program and discover what the secret message is. (Trust me, there is one) Otherwise, you can also copy and paste the following program if you're really anxious to perform the secret task.

Also, for those curious, here is the palindrome used. I had to remove the spaces so checking it in the program would be easier.

"Are we not drawn onward, we few, drawn onward to new era?"



Code

Solution Code

Back to the Program-A-Day homepage