Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my string change during a Caesar Cipher?

I am making a Caesar Cipher for fun and training. I discover a "strange" behavior in my test.

The two last lines return an error. They are not "ok". I dont know where I am wrong.

You can try my full code on dotnetfiddle.

Output

0000 RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
0001 SboepnVujm.HfuSboepnTusjoh(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
[...]
0030 VerhsqYxmp.KixVerhsqWxvmrk(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
0031 WfsitrZynq.LjyWfsitrXywnsl(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
0032 Xgtjus[zor.MkzXgtjusYzxotm(); // ? Random[til.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ko
0033 Yhukvt\{ps.Nl{YhukvtZ{ypun(); // ? Random\{il.Ge{RandomS{ring(); // ? RandomUtil.GetRandomString(); // ? ko
ok 32
ko 2

Test

public static void Main()
{
    int okCounter = 0;
    const string str = "RandomUtil.GetRandomString(); // ?";
    int iter = str.Length;
    for (int i = 0; i < iter; i++)
    {
        var e = CaesarCipher.Encrypt(str, i);
        var d = CaesarCipher.Decrypt(e, i);
        Console.WriteLine("{0:D4} {1} {2} {3} {4}", i, e, d, str, str == d ? "ok" : "ko");
        if (str == d)
            okCounter++;
    }

    Console.WriteLine("ok " + okCounter);
    Console.WriteLine("ko " + (iter - okCounter));
}

Caesar Cipher Class

public static string Encrypt(string input, int code)
{
    return RunCipher(input, code);
}

public static string Decrypt(string input, int code)
{
    return RunCipher(input, -code);
}

private static string RunCipher(string letters, int shift)
{
    return new String(MoveLetters(letters, shift).ToArray());
}

private static IEnumerable<char> MoveLetters(string letters, int shift)
{
    return
        from letter in letters
        let l = (char)(letter + shift)
        let diffCase = Char.IsLower(letter) ? 0 : 32
        let max = 'z' - diffCase
        let min = 'a' - diffCase
        let isAsciiLetter = letter >= min && letter <= max
        select isAsciiLetter ? (char)(l > max ? l - 26 : l < min ? l + 26 : l) : letter;
}
like image 532
aloisdg Avatar asked Jul 27 '26 22:07

aloisdg


1 Answers

in MoveLetter() you have line

let l = (char)(letter + shift)

it moves out of alphabet charachers code range, when shift > 26

so you need at least change it to

let l = (char)(letter + shift%26)

or add a check in your code to avoid shift <= 0 and shift >= 26 because they doesn't make much sense in a Caesar Cipher

like image 83
ASh Avatar answered Jul 29 '26 12:07

ASh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!