private static char Rotate(char value, int shift, Range range) {
int mod = (range.End.Value - range.Start.Value + 1);
return (char) (range.Start.Value +
((value - range.Start.Value + shift % mod) % mod + mod) % mod);
private static string doEncryption(string input, int key) {
return string.Concat(input.Select(c =>
c >= 'a' && c <= 'z' ? Rotate(c, key, 'a'..'z')
: c >= 'A' && c <= 'Z' ? Rotate(c, key, 'A'..'Z')
: c >= '0' && c <= '9' ? Rotate(c, key, '0'..'9')
private static string doDecryption(string input, int key) =>
doEncryption(input, -key);
public static void Main() {
string[] tests = new string[] {
string result = String.Join(Environment.NewLine, tests
.Select(test => (plain: test, code: doEncryption(test, key)))
.Select(pair => $"{pair.plain,-12} => {pair.code,-12} => {doDecryption(pair.code, key)}"));