Task: Chaocipher





Java: import java.util.Arrays;

public class Chaocipher {
    private enum Mode {
        ENCRYPT,
        DECRYPT
    }

    private static final String L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
    private static final String R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC";

    private static int indexOf(char[] a, char c) {
        for (int i = 0; i < a.length; ++i) {
            if (a[i] == c) {
                return i;
            }
        }
        return -1;
    }

    private static String exec(String text, Mode mode) {
        return exec(text, mode, false);
    }

    private static String exec(String text, Mode mode, Boolean showSteps) {
        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) {
                System.out.printf("%s  %s\n", new String(left), new String(right));
            }
            int index;
            if (mode == Mode.ENCRYPT) {
                index = indexOf(right, text.charAt(i));
                eText[i] = left[index];
            } else {
                index = indexOf(left, text.charAt(i));
                eText[i] = right[index];
            }
            if (i == text.length() - 1) {
                break;
            }

            

            if (26 - index >= 0) System.arraycopy(left, index, temp, 0, 26 - index);
            System.arraycopy(left, 0, temp, 26 - index, index);
            char store = temp[1];
            System.arraycopy(temp, 2, temp, 1, 12);
            temp[13] = store;
            left = Arrays.copyOf(temp, temp.length);

            

            if (26 - index >= 0) System.arraycopy(right, index, temp, 0, 26 - index);
            System.arraycopy(right, 0, temp, 26 - index, index);
            store = temp[0];
            System.arraycopy(temp, 1, temp, 0, 25);
            temp[25] = store;
            store = temp[2];
            System.arraycopy(temp, 3, temp, 2, 11);
            temp[13] = store;
            right = Arrays.copyOf(temp, temp.length);
        }

        return new String(eText);
    }

    public static void main(String[] args) {
        String plainText = "WELLDONEISBETTERTHANWELLSAID";
        System.out.printf("The original plaintext is : %s\n", plainText);
        System.out.println("\nThe left and right alphabets after each permutation during encryption are:");
        String cipherText = exec(plainText, Mode.ENCRYPT, true);
        System.out.printf("\nThe cipher text is : %s\n", cipherText);
        String plainText2 = exec(cipherText, Mode.DECRYPT);
        System.out.printf("\nThe recovered plaintext is : %s\n", plainText2);
    }
}







Ada: with Ada.Text_IO; use Ada.Text_IO;

procedure chao_slices is
   type iMode is (Encrypt, Decrypt);

   L_Alphabet : String := "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
   R_Alphabet : String := "PTLNBQDEOYSFAVZKGJRIHWXUMC";
   plaintext  : String := "WELLDONEISBETTERTHANWELLSAID";
   ciphertext : String (1 .. plaintext'length);
   plaintext2 : String (1 .. plaintext'length);
   offset     : Natural;

   function IndexOf (Source : String; Value : Character) return Positive is
      Result : Positive;

   begin
      for I in Source'Range loop
         if Source (I) = Value then
            Result := I;
            exit;
         end if;
      end loop;
      return Result;
   end IndexOf;

   function Exec
     (Text : String; mode : iMode; showsteps : Boolean := False) return String
   is
      etext : String (Text'First .. Text'Last);
      temp  : String (1 .. 26);
      index : Positive;
      store : Character;
      left  : String := L_Alphabet;
      right : String := R_Alphabet;
   begin
      for I in Text'Range loop
         if showsteps then
            Put_Line (left & "  " & right);
         end if;

         if mode = Encrypt then
            index     := IndexOf (Source => right, Value => Text (I));
            etext (I) := left (index);
         else
            index     := IndexOf (Source => left, Value => Text (I));
            etext (I) := right (index);
         end if;

         exit when I = Text'Last;

         
         
         

         if index > 1 then
            offset                 := 26 - index;
            temp (1 .. offset + 1) := left (index .. index + offset);

            temp (offset + 2 .. 26) := left (1 .. index - 1);
            store                   := temp (2);

            temp (2 .. 13) := temp (3 .. 14);
            temp (14)      := store;
            left           := temp;

            
            
            

            temp (1 .. offset + 1) := right (index .. index + offset);

            temp (offset + 2 .. 26) := right (1 .. index - 1);
            store                   := temp (1);

            temp (1 .. 25) := temp (2 .. 26);
            temp (26)      := store;
            store          := temp (3);

            temp (3 .. 13) := temp (4 .. 14);
            temp (14)      := store;
            right          := temp;
         end if;

      end loop;

      return etext;

   end Exec;
begin
   Put_Line ("The original text is : " & plaintext);
   New_Line;
   Put_Line
     ("The left and right alphabets after each permutation during encryption are:");
   New_Line;
   ciphertext := Exec (plaintext, Encrypt, True);
   New_Line;
   Put_Line ("The ciphertext is : " & ciphertext);
   plaintext2 := Exec (ciphertext, Decrypt);
   New_Line;
   Put_Line ("The recovered plaintext is : " & plaintext2);
end chao_slices;