Task: Chaocipher



C#: using System;

namespace Chaocipher {
    enum Mode {
        ENCRYPT,
        DECRYPT,
    }

    class Program {
        const string L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
        const string R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC";

        static string Exec(string text, Mode mode, bool showSteps = false) {
            char[] left = L_ALPHABET.ToCharArray();
            char[] right = R_ALPHABET.ToCharArray();
            char[] eText = new char[text.Length];
            char[] temp = new char[26];

            for (int i = 0; i < text.Length; ++i) {
                if (showSteps) Console.WriteLine("{0} {1}", string.Join("", left), string.Join("", right));
                int index = 0;
                if (mode == Mode.ENCRYPT) {
                    index = Array.IndexOf(right, text[i]);
                    eText[i] = left[index];
                } else {
                    index = Array.IndexOf(left, text[i]);
                    eText[i] = right[index];
                }
                if (i == text.Length - 1) break;

                

                for (int j = index; j < 26; ++j) temp[j - index] = left[j];
                for (int j = 0; j < index; ++j) temp[26 - index + j] = left[j];
                var store = temp[1];
                for (int j = 2; j < 14; ++j) temp[j - 1] = temp[j];
                temp[13] = store;
                temp.CopyTo(left, 0);

                

                for (int j = index; j < 26; ++j) temp[j - index] = right[j];
                for (int j = 0; j < index; ++j) temp[26 - index + j] = right[j];
                store = temp[0];
                for (int j = 1; j < 26; ++j) temp[j - 1] = temp[j];
                temp[25] = store;
                store = temp[2];
                for (int j = 3; j < 14; ++j) temp[j - 1] = temp[j];
                temp[13] = store;
                temp.CopyTo(right, 0);
            }

            return new string(eText);
        }

        static void Main(string[] args) {
            var plainText = "WELLDONEISBETTERTHANWELLSAID";
            Console.WriteLine("The original plaintext is : {0}", plainText);
            Console.WriteLine("\nThe left and right alphabets after each permutation during encryption are :\n");
            var cipherText = Exec(plainText, Mode.ENCRYPT, true);
            Console.WriteLine("\nThe ciphertext is : {0}", cipherText);
            var plainText2 = Exec(cipherText, Mode.DECRYPT);
            Console.WriteLine("\nThe recovered plaintext is : {0}", plainText2);
        }
    }
}





Python: 



def main():
    
    lalpha = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
    ralpha = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
    msg = "WELLDONEISBETTERTHANWELLSAID"

    print("L:", lalpha)
    print("R:", ralpha)
    print("I:", msg)
    print("O:", do_chao(msg, lalpha, ralpha, 1, 0), "\n")
    
    do_chao(msg, lalpha, ralpha, 1, 1)

def do_chao(msg, lalpha, ralpha, en=1, show=0):
    msg = correct_case(msg)
    out = ""    
    if show:
        print("="*54)        
        print(10*" " + "left:" + 21*" " + "right: ")
        print("="*54)        
        print(lalpha, ralpha, "\n")
    for L in msg:
        if en:
            lalpha, ralpha = rotate_wheels(lalpha, ralpha, L)
            out += lalpha[0]
        else:
            ralpha, lalpha = rotate_wheels(ralpha, lalpha, L)
            out += ralpha[0]
        lalpha, ralpha = scramble_wheels(lalpha, ralpha)
        if show:
            print(lalpha, ralpha)            
    return out
    
def makealpha(key=""):
    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    z = set()
    key = [x.upper() for x in (key + alpha[::-1])
           if not (x.upper() in z or z.add(x.upper()))]
    return "".join(key)

def correct_case(string):
    return "".join([s.upper() for s in string if s.isalpha()])

def permu(alp, num):
    alp = alp[:num], alp[num:]
    return "".join(alp[::-1])

def rotate_wheels(lalph, ralph, key):
    newin = ralph.index(key)
    return permu(lalph, newin), permu(ralph, newin)    

def scramble_wheels(lalph, ralph):
    
    
    lalph = list(lalph)
    lalph = "".join([*lalph[0],
                    *lalph[2:14],
                    lalph[1],
                    *lalph[14:]])
    
    
    
    
    ralph = list(ralph)
    ralph = "".join([*ralph[1:3],
                     *ralph[4:15],
                     ralph[3],
                     *ralph[15:],
                     ralph[0]])
    return lalph, ralph

main()