1

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);
    }
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
0xdw
  • 3,755
  • 2
  • 25
  • 40
  • Can you add some context, obviously no one is going to implement security this weak in the real world. – Jeremy Thompson Sep 24 '22 at 03:31
  • @JeremyThompson, Of course, that's true :) This is just a question of a paper. Just wonder if I can solve that. – 0xdw Sep 24 '22 at 03:49
  • Did you come up with the 3rd rule yourself? Because "a" and "z" will result in same string. – shingo Sep 24 '22 at 04:00
  • 1
    For those wondering, this sort of "encryption" is a common homework question. It's not about encryption. It's about learning the basic operations needed to manipulate the data. – John Sep 24 '22 at 04:02
  • I think that you have misinterpreted rule 3. That rule simply means that, when advancing, you wrap to the beginning when you go past the end. It doesn't mean that you replace Z with A and then start advancing from there. It means that advancing one place from Z takes you back to A at the beginning. – John Sep 24 '22 at 04:29

1 Answers1

2

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".

John
  • 3,057
  • 1
  • 4
  • 10
  • `E` or `F`? The last char... Supposed to return `Insnsiz-12F`.. – dr.null Sep 24 '22 at 04:09
  • @dr.null, I addressed this specifically. Start at Z, advance 5 characters and wrap from Z to A. Count with me: Z+1=A, Z+2=B, Z+3=C, Z+4=D, Z+5=E. Any more questions. – John Sep 24 '22 at 04:15
  • No Thanks. Relax Mr. John. – dr.null Sep 24 '22 at 04:20
  • @dr.null, only if [Frankie says so](https://www.bing.com/images/search?q=frankie+says+relax&qpvt=frankie+says+relax&tsc=ImageHoverTitle&form=IGRE&first=1). Are you old enough for that to mean something to you? – John Sep 24 '22 at 05:05
  • hahaha good one. unfortunately yes, grandpa here. – dr.null Sep 24 '22 at 05:07