Reputation: 1859
If I want to write a Caesar cipher C# do I have to go through every case? It doesn't make sense to me to convert to ASCII or UTF (probably because I don't understand how it would work). I just need a point in the right direction.
Should I assign each letter the numbers 1-26?
Upvotes: 5
Views: 8850
Reputation: 1
I made a simple class that handles lowercase, uppercase and numbers. It uses the StringBuilder
class to make the output. To decode a string, you would use the opposite shift
(if you encrypt with shift = 2, decrypt with shift = -2). I'm also kind of new to C# and come from a C++ background, but I hope this approach works for you or makes it clear how to approach it. I tried commenting so the functionality is clear:
class Cypher
{
static public String CaesarCipher(String input, int shift = 1) {
if(shift==0) return input;
StringBuilder builder = new StringBuilder(); //stringbuilder class for ease of use
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
char c2 = c;
if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'))) {
c2 = (char)(c + shift); //make the shift
if ((c >= 'a') && (c <= 'z')) //original char is in this range
{
c2 = CharBindToRange(c2, 'a', 'z'); //clamp the shifted char to range
}
else if ((c >= 'A') && (c <= 'Z'))
{
c2 = CharBindToRange(c2, 'A', 'Z');
}
else if ((c >= '0') && (c <= '9'))
{
c2 = CharBindToRange(c2, '0', '9');
}
}
builder.Append(c2); //add the processed character to output
}
return builder.ToString(); //return the processed string
}
static protected char CharBindToRange(char cinp, char low, char high) //clamps char to specified range
{
if (low >= high) { return '?'; }
if(cinp>high)
{
cinp = (char)(low + (cinp - high) - 1);
}
else if (cinp < low)
{
cinp = (char)(high - (low - cinp) + 1);
}
return cinp;
}
}
Upvotes: 0
Reputation: 3060
This is my approach.
public static string Encrypt(string str, int n)
{
return string.Join("", str.Select(x => Encrypt(x, n)));
}
public static string Decrypt(string str, int n)
{
return string.Join("", str.Select(x => Decrypt(x, n)));
}
public static char Encrypt(char chr, int n)
{
int x = chr - 65;
return (char)((65) + ((x + n) % 26));
}
public static char Decrypt(char chr, int n)
{
int x = chr - 65;
return (char)((65) + ((x - n) % 26));
}
P.S.
Works only for uppercase letters.
Read the Wikipedia article: Caesar cipher
Upvotes: 1
Reputation: 5423
Perhaps dropping hints would be helpful - you say you don't want to copy or be told the answer:
char[] chars = new char[]{'a', 'b',...};
Upvotes: 1
Reputation: 2158
You could put each letter into an array and use the array index (wrapping at the end) or you could simply use the asccii value of the letter and wrap to the first when reaching the last. The trick here is that all the characters are coninuously sorted, starting at A=0x41
Upvotes: 2
Reputation: 113392
For a traditional Caesar Cypher, you'd check a char was in the range [a-z] or [A-Z], and just pass it plain otherwise.
An alternative is to treat all characters in the same way, so not only does a become b, but µ becomes ¶ and you wrap around at U+10FFFF (the highest codepoint in Unicode) becomes U+0000 (the former is a non-character and the latter a null character, but there's no reason why a string
can't hold them to transmit to another place.
In between those two, is to act on the UTF-16. That is, you just add 1 to the value of each char
, and wrap U+FFFF through to U+0000. The output could become an invalid UTF-16 string (because it could have mis-matched surrogates, but that wouldn't prevent you from passing it around in a string
, and then decyphering it again. After all, modern encryption doesn't result in valid strings either.
Upvotes: 1