C# Simple encrypt/decrypt algorithm

Viewed 65

I was working on straightforward encryption and got stuck on one of its rules.

The rules are,

  1. Encryption work by adding 5 to each character.
  2. Only encrypt a-z and A-Z, all other characters will add to the encrypted string as it is.
  3. If the character is z or Z, the adding starts from the character a.
  4. By performing the above encryption in reverse, the description should also be present.

I was able to do the encryption, but the 3rd rule is where I got stuck when decrypting.

Below is the code I tried,

# Encrypt
Input  : Dinindu-12Z
Output : Insnsiz-12F
# Decrypt
Input  : Insnsiz-12F
Output : Dinindu-12Z # This is the expected output, but got "Dinind\-12A"
using System;

class Program
{
    public static String encrypt(String input)
    {
        String output = "";
        foreach (char c in input)
        {
            if (char.IsLetter(c))
            {
                char cc = c;
                if (c == 'z') cc = 'a';
                if (c == 'Z') cc = 'A';
                output += (char)(((int)cc) + 5);
            }
            else
            {
                output += c;
            }
        }
        return output;
    }

    public static string decrypt(String input)
    {
        String output = "";
        foreach (char c in input)
        {
            if (char.IsLetter(c))
            {
                char cc = c;
                if (c == 'z') cc = 'a';
                if (c == 'Z') cc = 'A';
                output += (char)(((int)cc) - 5);
            }
            else
            {
                output += c;
            }
        }
        return output;
    }

    public static void Main(string[] args)
    {
        String a = encrypt("Dinindu-12Z");
        String b = decrypt(a);
        Console.WriteLine(a);
        Console.WriteLine(b);
    }
}
1 Answers

You should write a method that will accept a char array and get the element at the advanced index. You can use the modulo (%) operator to advance and wrap, e.g.

private static char GetCharWithStepAndWrap(char[] chars, char ch, int step)
{
    var index = Array.IndexOf(chars, ch);

    index += step;
    index %= chars.Length;

    return chars[index];
}

Adding the step value will advance the index, possibly past the end of the array. The modulo will then divide the index by the Length of the array and use the remainder. That means that if the index starts within the array, it will stay where it is and, if it's past the end of the array, you're effectively subtracting the Length from it to wrap back to the beginning.

You can then use that method with a char array from a to z to encrypt and then simply reverse the array to decrypt, e.g.

static void Main(string[] args)
{
    var chars = Enumerable.Range(Convert.ToInt32('a'), 26).Select(Convert.ToChar).ToArray();
    var plainText = "Dinindu-12Z";
    var encryptedText = string.Empty;

    for (var i = 0; i < plainText.Length; i++)
    {
        var ch = plainText[i];

        if (char.IsLetter(ch))
        {
            var isUpper = char.IsUpper(ch);

            ch = char.ToLower(ch);
            ch = GetCharWithStepAndWrap(chars, ch, 5);

            if (isUpper)
            {
                ch = char.ToUpper(ch);
            }
        }

        encryptedText += ch;
    }

    Console.WriteLine(encryptedText);

    Array.Reverse(chars);

    var decryptedText = string.Empty;

    for (var i = 0; i < plainText.Length; i++)
    {
        var ch = encryptedText[i];

        if (char.IsLetter(ch))
        {
            var isUpper = char.IsUpper(ch);

            ch = char.ToLower(ch);
            ch = GetCharWithStepAndWrap(chars, ch, 5);

            if (isUpper)
            {
                ch = char.ToUpper(ch);
            }
        }

        decryptedText += ch;
    }

    Console.WriteLine(decryptedText);
}

If you try that code, you'll notice that the correct encrypted text is "Insnsiz-12E".

Related