This problem is relatively straightforward. Simply loop through the message's letters and shift them by some amount.
The example solution uses the following string extension method to encrypt a string:
// Use a Caesar cipher to encrypt the plaintext.
public static string CaesarEncrypt(this string plaintext, int shift)
{
plaintext = plaintext.StripText();
// Encrypt.
char[] chars = new char[plaintext.Length];
for (int i = 0; i < plaintext.Length; i++)
{
int ch = plaintext[i] - 'A';
ch = (ch + shift + 26) % 26;
chars[i] = (char)('A' + ch);
}
return new string(chars).ToFiveGrams();
}
This method calls the StripText extension method described shortly to remove any non-letter characters from the string. It then loops through the message's letters, adding the shift to each and storing the results in a char array. When it has finished processing the letters, the method converts the char array into a string, calls the ToFiveGrams extension method (also described shortly), and returns the result.
The following code shows the StripText helper extension method:
// Convert to uppercase, and remove punctuation and spaces.
public static string StripText(this string text)
{
text = text.ToUpper();
text = new string(text.Where(
ch => (ch >= 'A') && (ch <= 'Z')).ToArray());
return text;
}
This method converts the message into uppercase. It uses a lambda expression to extract the characters between A and Z, and converts those characters into a new string. That removes any non-letter characters from the string. The method then returns the result.
The following code shows the ToFiveGrams helper method:
// Separate the string into five-character pieces.
public static string ToFiveGrams(this string text)
{
StringBuilder result = new StringBuilder();
for (int i = 0; i < text.Length; i += 5)
{
int length = Math.Min(5, text.Length - i);
result.Append(" " + text.Substring(i, length));
}
result.Remove(0, 1);
return result.ToString();
}
The code first creates a StringBuilder to hold the result. It breaks the text into groups of five characters and adds the groups preceded by a space character to the StringBuilder. After it has finished processing the text, the code removes the first space character, converts the rest of the StringBuilder contents into a string, and returns the result.
After you write the method to encrypt a string, decrypting a string is easy because decrypting a Caesar cipher message is the same as encrypting it with a negative shift. For example, if you encrypt a plaintext message with the shift 4, then you can decrypt it by encrypting the ciphertext with a shift of -4. The CaesarDecrypt method shown in the following code does that:
// Use a Caesar cipher to decrypt the ciphertext.
public static string CaesarDecrypt(this string ciphertext, int shift)
{
return ciphertext.CaesarEncrypt(-shift);
}
This method simply calls the CaesarEncrypt method described earlier to encrypt the ciphertext with a negative shift value.
Download the CaesarCipher example solution to see additional details.