I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Chaocipher

Chaocipher
You are encouraged to solve this task according to the task description, using any language you may know.
Description

The Chaocipher was invented by J.F.Byrne in 1918 and, although simple by modern cryptographic standards, does not appear to have been broken until the algorithm was finally disclosed by his family in 2010.

The algorithm is described in this paper by M.Rubin in 2010 and there is a C# implementation here.

Code the algorithm in your language and to test that it works with the plaintext 'WELLDONEISBETTERTHANWELLSAID' used in the paper itself.

## 11l

Translation of: Python
`F correct_case(string)   R string.filter(s -> s.is_alpha()).map(s -> s.uppercase()).join(‘’) F permu(String alp; num)   R alp[num..]‘’alp[0 .< num] F rotate_wheels(lalph, ralph, key)   V newin = ralph.index(key)   R (permu(lalph, newin), permu(ralph, newin)) F scramble_wheels(String =lalph, String =ralph)   lalph = lalph[0]‘’lalph[2.<14]‘’lalph[1]‘’lalph[14..]   ralph = ralph[1.<3]‘’ralph[4.<15]‘’ralph[3]‘’ralph[15..]‘’ralph[0]   R (lalph, ralph) F do_chao(=msg, =lalpha, =ralpha, en = 1B, show = 0B)   msg = correct_case(msg)   V out = ‘’   I show      print(‘=’ * 54)      print((10 * ‘ ’)‘left:’(21 * ‘ ’)‘right: ’)      print(‘=’ * 54)      print(lalpha‘ ’ralpha" \n")   L(l) msg      I en         (lalpha, ralpha) = rotate_wheels(lalpha, ralpha, l)         out ‘’= lalpha[0]      E         (ralpha, lalpha) = rotate_wheels(ralpha, lalpha, l)         out ‘’= ralpha[0]      (lalpha, ralpha) = scramble_wheels(lalpha, ralpha)      I show         print(lalpha‘ ’ralpha)   R out V lalpha = ‘HXUCZVAMDSLKPEFJRIGTWOBNYQ’V ralpha = ‘PTLNBQDEOYSFAVZKGJRIHWXUMC’V msg = ‘WELLDONEISBETTERTHANWELLSAID’ print(‘L: ’lalpha)print(‘R: ’ralpha)print(‘I: ’msg)V o = do_chao(msg, lalpha, ralpha, 1B, 0B)print(‘O: ’o)print(‘D: ’do_chao(o, lalpha, ralpha, 0B, 0B))print() do_chao(msg, lalpha, ralpha, 1B, 1B)`
Output:
```L: HXUCZVAMDSLKPEFJRIGTWOBNYQ
R: PTLNBQDEOYSFAVZKGJRIHWXUMC
I: WELLDONEISBETTERTHANWELLSAID
O: OAHQHCNYNXTSZJRRHJBYHQKSOUJY
D: WELLDONEISBETTERTHANWELLSAID

======================================================
left:                     right:
======================================================
HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC

ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI
YFJBGMTKWNOQXCHIDVALZRSPUE JIBMESWKYZXUCOPRTLNHFAGVQD
```

This solution uses array slices to permute the left and right strings. Use of slices clarifies the looping logic. Ada strings are indexed with the predefined subtype Positive which begins at 1.

` 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;          -- permute left         -- The array value permutations are performed using array slices         -- rather than explicit loops          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;             -- permute right            -- The array value permutations are performed using array slices            -- rather than explicit loops             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; `
Output:
```The original text is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are:

HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
UJIDLGMTONQXCFVAZRBSKWPEYH  LNHMSAVKGQDJOIBERYFWZXUCPT
DRBSKWPEYHUJIZLGMTONQXCFVA  YFZXUCPTLNHMSWVKGQDJOIBERA

The ciphertext is : OAHQHCNYNXTSZJRRUIDHIXWKPKLY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
```

## AppleScript

`-- Chaocipher algorithm by J.F.Byrne 1918.on chaocipher(input, |key|, mode)    -- input: text to be enciphered or deciphered.    -- |key|: script object or record with leftAlpha and rightAlpha properties, each of whose values is a shuffled alphabet text.    -- mode: the text "encipher" or "decipher".    script o        property inputChars : input's characters        property leftAlpha : |key|'s leftAlpha's characters        property rightAlpha : |key|'s rightAlpha's characters        property inAlpha : leftAlpha        property outAlpha : rightAlpha        property output : {}    end script     set alphaLen to (count o's leftAlpha)    if ((count o's rightAlpha) ≠ alphaLen) then error    if (mode is "encipher") then        set {o's inAlpha, o's outAlpha} to {o's rightAlpha, o's leftAlpha}    else if (mode is not "decipher") then        error    end if    set zenith to 1    set nadir to alphaLen div 2 + 1    repeat with char in o's inputChars        set char to char's contents        set found to false        repeat with i from 1 to alphaLen            if (o's inAlpha's item i = char) then                set end of o's output to o's outAlpha's item i                set found to true                exit repeat            end if        end repeat        if (found) then            rotate(o's leftAlpha, zenith, alphaLen, -(i - zenith))            rotate(o's leftAlpha, zenith + 1, nadir, -1)            rotate(o's rightAlpha, zenith, alphaLen, -i)            rotate(o's rightAlpha, zenith + 2, nadir, -1)        end if    end repeat     return join(o's output, "")end chaocipher on rotate(theList, l, r, amount)    set listLength to (count theList)    if (listLength < 2) then return    if (l < 0) then set l to listLength + l + 1    if (r < 0) then set r to listLength + r + 1    if (l > r) then set {l, r} to {r, l}    script o        property lst : theList        property storage : missing value    end script     set rangeLength to r - l + 1    set amount to (rangeLength + rangeLength - amount) mod rangeLength    if (amount is 0) then return    set o's storage to o's lst's items l thru (l + amount - 1)    repeat with i from (l + amount) to r        set o's lst's item (i - amount) to o's lst's item i    end repeat    set j to r - amount    repeat with i from 1 to amount        set o's lst's item (j + i) to o's storage's item i    end repeatend rotate on join(lst, delim)    set astid to AppleScript's text item delimiters    set AppleScript's text item delimiters to delim    set txt to lst as text    set AppleScript's text item delimiters to astid    return txtend join -- Return a script object containing a couple of randomised alphabets to use as a choacipher key.on makeKey()    set lAlpha to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"'s characters    copy lAlpha to rAlpha    script |key|        property leftAlpha : join(shuffle(lAlpha, 1, -1), "")        property rightAlpha : join(shuffle(rAlpha, 1, -1), "")    end script     return |key|end makeKey -- Fisher-Yates (aka Durstenfeld, aka Knuth) shuffle.on shuffle(theList, l, r)    set listLength to (count theList)    if (listLength < 2) then return array    if (l < 0) then set l to listLength + l + 1    if (r < 0) then set r to listLength + r + 1    if (l > r) then set {l, r} to {r, l}    script o        property lst : theList    end script     repeat with i from l to (r - 1)        set j to (random number from i to r)        set v to o's lst's item i        set o's lst's item i to o's lst's item j        set o's lst's item j to v    end repeat     return theListend shuffle -- Demo using the two-alphabet key from the Rubin paper and another generated at random.-- Decription must be with the key that was used for the encription.on demo(originalText)    set key1 to {leftAlpha:"HXUCZVAMDSLKPEFJRIGTWOBNYQ", rightAlpha:"PTLNBQDEOYSFAVZKGJRIHWXUMC"}    set key2 to makeKey()    set enciphered to chaocipher(originalText, key1, "encipher")    set doubleEnciphered to chaocipher(enciphered, key2, "encipher")    set deDoubleEnciphered to chaocipher(doubleEnciphered, key2, "decipher")    set deciphered to chaocipher(deDoubleEnciphered, key1, "decipher")    return join({"Original text = " & originalText, ¬        "Enciphered = " & enciphered, "Double enciphered = " & doubleEnciphered, ¬        "De-double enciphered = " & deDoubleEnciphered, "Deciphered  = " & deciphered}, linefeed)end demodemo("WELLDONEISBETTERTHANWELLSAID")`
Output:
`"Original text = WELLDONEISBETTERTHANWELLSAIDEnciphered = OAHQHCNYNXTSZJRRHJBYHQKSOUJYDouble enciphered = ZJVDGIXNNDNRHAXQUUJZGAFTANHWDe-double enciphered = OAHQHCNYNXTSZJRRHJBYHQKSOUJYDeciphered  = WELLDONEISBETTERTHANWELLSAID"`

## Arc

`(= lshift '((0 1) (2 14) (1 2) (14 26)))(= rshift '((1 3) (4 15) (3 4) (15 26) (0 1))) (= rot (fn (alpha shift)  (let shift (mod shift 26)    (string (cut alpha shift) (cut alpha 0 shift))))) (= scramble-wheel (fn (alpha moves)  (= oput '())  (up i 0 (- (len moves) 1)      (push (cut alpha ((moves i) 0) ((moves i) 1)) oput))  (= oput (string (rev oput))))) (= chaocipher (fn (left right msg (o crypted) (o dec?))  (unless crypted    (prn "Encoding " msg " with chaocipher")    (prn left " " right))  (when dec? (swap left right))    (= offset ((positions (msg 0) right) 0))    (= left (rot left offset))    (= right (rot right offset))    (push (cut left 0 1) crypted)  (when dec? (swap left right))  (prn (scramble-wheel left lshift)   " " (scramble-wheel right rshift))  (if (> (len msg) 1)      (chaocipher (scramble-wheel left lshift)             (scramble-wheel right rshift)                  (cut msg 1) crypted dec?)      (string (rev crypted))))) (chaocipher "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC"            "WELLDONEISBETTERTHANWELLSAID")(chaocipher "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC"            "OAHQHCNYNXTSZJRRHJBYHQKSOUJY" nil 1) `
Output:
` arc> (chaocipher "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC"                 "WELLDONEISBETTERTHANWELLSAID")Encoding WELLDONEISBETTERTHANWELLSAID with chaocipherHXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMCONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHWADBSLKPEFJRIGMTWONYQHXUCZV OYSFAVZKGJRIHMWXUCPTLNBQDEHUCZVADBSLKPEXFJRIGMTWONYQ NBDEOYSFAVZKGQJRIHMWXUCPTLQUCZVADBSLKPEHXFJRIGMTWONY NBEOYSFAVZKGQDJRIHMWXUCPTLHFJRIGMTWONYQXUCZVADBSLKPE JRHMWXUCPTLNBIEOYSFAVZKGQDCVADBSLKPEHFJZRIGMTWONYQXU YSAVZKGQDJRHMFWXUCPTLNBIEONQXUCVADBSLKPYEHFJZRIGMTWO BIOYSAVZKGQDJERHMFWXUCPTLNYHFJZRIGMTWONEQXUCVADBSLKP RHFWXUCPTLNBIMOYSAVZKGQDJENQXUCVADBSLKPEYHFJZRIGMTWO MOSAVZKGQDJERYHFWXUCPTLNBIXCVADBSLKPEYHUFJZRIGMTWONQ AVKGQDJERYHFWZXUCPTLNBIMOSTONQXCVADBSLKWPEYHUFJZRIGM IMSAVKGQDJERYOHFWZXUCPTLNBSKWPEYHUFJZRILGMTONQXCVADB RYHFWZXUCPTLNOBIMSAVKGQDJEZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPTJILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPTRBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBERSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBERHFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPTJDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNHBGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWAYFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLNHIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESWQXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBEKPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTLSPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTLOQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMESUEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFAJBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJIYFJBGMTKWNOQXCHIDVALZRSPUE JIBMESWKYZXUCOPRTLNHFAGVQD"OAHQHCNYNXTSZJRRHJBYHQKSOUJY" `

## AutoHotkey

`LeftW := "HXUCZVAMDSLKPEFJRIGTWOBNYQ"RghtW := "PTLNBQDEOYSFAVZKGJRIHWXUMC" PlainText    := "WELLDONEISBETTERTHANWELLSAID"CipherText    := Chao_Cipher(PlainText, LeftW, RghtW)     ; "OAHQHCNYNXTSZJRRHJBYHQKSOUJY"DecipherText:= Chao_Decipher(CipherText, LeftW, RghtW)    ; "WELLDONEISBETTERTHANWELLSAID" MsgBox % Result := "Original text:`t" PlainText "`nCipher text:`t" CipherText "`nDecipher text:`t" DecipherTextreturn;-------------------------------------------Chao_Cipher(PT, LeftW, RghtW){    oRght:=StrSplit(RghtW), oLeft:=StrSplit(LeftW)    for i, p in StrSplit(PT){        result .= (c := Key2Val(oRght, oLeft, p))        oLeft:=Permute(oLeft, c, 1)        oRght:=Permute(oRght, p)    }    return result};-------------------------------------------Chao_Decipher(CT, LeftW, RghtW){    oRght:=StrSplit(RghtW), oLeft:=StrSplit(LeftW)    for i, c in StrSplit(CT){        result .= (p := Key2Val(oLeft, oRght, c))        oLeft:=Permute(oLeft, c, 1)        oRght:=Permute(oRght, p)    }        return result};-------------------------------------------Key2Val(Key, Val, char){    for i, ch in Key        if (ch = char)            return Val[i]};-------------------------------------------Permute(Arr, ch, dt:=0){    for i, c in Arr        if (c=ch)            break    loop % i-dt        Arr.Push(Arr.RemoveAt(1))               ; shift left    ch := Arr[3-dt]                             ; save 2nd/3rd chr    loop % 11+dt        Arr[A_Index+2-dt]:=Arr[A_Index+3-dt]    ; shift pos 3/4-14 left    Arr[14] := ch                               ; place 2nd/3rd chr in pos 14    return Arr}`
Output:
```Original text:	WELLDONEISBETTERTHANWELLSAID
Cipher text:	OAHQHCNYNXTSZJRRHJBYHQKSOUJY
Decipher text:	WELLDONEISBETTERTHANWELLSAID```

## C

Translation of: Kotlin
`#include <stdio.h>#include <string.h>#include <stdlib.h> #define TRUE 1#define FALSE 0 typedef int bool;typedef enum { ENCRYPT, DECRYPT } cmode; const char *l_alphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";const char *r_alphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC"; void chao(const char *in, char *out, cmode mode, bool show_steps) {    int i, j, index;    char store;    size_t len = strlen(in);    char left[27], right[27], temp[27];    strcpy(left, l_alphabet);    strcpy(right, r_alphabet);    temp[26] = '\0';     for (i = 0; i < len; ++i ) {        if (show_steps) printf("%s  %s\n", left, right);        if (mode == ENCRYPT) {            index = strchr(right, in[i]) - right;            out[i] = left[index];        }        else {            index = strchr(left, in[i]) - left;            out[i] = right[index];        }        if (i == len - 1) break;         /* permute left */         for (j = index; j < 26; ++j) temp[j - index] = left[j];        for (j = 0; j < index; ++j) temp[26 - index + j] = left[j];        store = temp[1];        for (j = 2; j < 14; ++j) temp[j - 1] = temp[j];        temp[13] = store;        strcpy(left, temp);         /* permute right */         for (j = index; j < 26; ++j) temp[j - index] = right[j];        for (j = 0; j < index; ++j) temp[26 - index + j] = right[j];        store = temp[0];        for (j = 1; j < 26; ++j) temp[j - 1] = temp[j];        temp[25] = store;        store = temp[2];        for (j = 3; j < 14; ++j) temp[j - 1] = temp[j];        temp[13] = store;        strcpy(right, temp);    }} int main() {    const char *plain_text = "WELLDONEISBETTERTHANWELLSAID";    char *cipher_text = malloc(strlen(plain_text) + 1);    char *plain_text2 = malloc(strlen(plain_text) + 1);    printf("The original plaintext is : %s\n", plain_text);    printf("\nThe left and right alphabets after each permutation"           " during encryption are :\n\n");    chao(plain_text, cipher_text, ENCRYPT, TRUE);    printf("\nThe ciphertext is : %s\n", cipher_text);    chao(cipher_text, plain_text2, DECRYPT, FALSE);    printf("\nThe recovered plaintext is : %s\n", plain_text2);    free(cipher_text);    free(plain_text2);    return 0;}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :

HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ  YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY  LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF  MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD  VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE  HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX  RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON  SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS  NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR  NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW  WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP  GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF  OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
```

## C#

Translation of: D
`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;                 // permute left                 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);                 // permute right                 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);        }    }}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :

HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

## C++

Translation of: C#
`#include <iostream> enum class Mode {    ENCRYPT,    DECRYPT,}; const std::string L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";const std::string R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC"; std::string exec(std::string text, Mode mode, bool showSteps = false) {    auto left = L_ALPHABET;    auto right = R_ALPHABET;    auto eText = new char[text.size() + 1];    auto temp = new char[27];     memset(eText, 0, text.size() + 1);    memset(temp, 0, 27);     for (size_t i = 0; i < text.size(); i++) {        if (showSteps) std::cout << left << ' ' << right << '\n';        size_t index;        if (mode == Mode::ENCRYPT) {            index = right.find(text[i]);            eText[i] = left[index];        } else {            index = left.find(text[i]);            eText[i] = right[index];        }        if (i == text.size() - 1) break;         // permute left         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];        auto store = temp[1];        for (int j = 2; j < 14; ++j) temp[j - 1] = temp[j];        temp[13] = store;        left = temp;         // permurte right         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;        right = temp;    }     return eText;} int main() {    auto plainText = "WELLDONEISBETTERTHANWELLSAID";    std::cout << "The original plaintext is : " << plainText << "\n\n";    std::cout << "The left and right alphabets after each permutation during encryption are :\n";    auto cipherText = exec(plainText, Mode::ENCRYPT, true);    std::cout << "\nThe ciphertext is : " << cipherText << '\n';    auto plainText2 = exec(cipherText, Mode::DECRYPT);    std::cout << "\nThe recovered plaintext is : " << plainText2 << '\n';     return 0;}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :
HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

## D

Translation of: Kotlin
`import std.stdio;import std.string; immutable L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";immutable R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC"; enum Mode {    ENCRYPT,    DECRYPT,} string exec(string text, Mode mode, bool showSteps = false) {    char[] left = L_ALPHABET.dup;    char[] right = R_ALPHABET.dup;    char[] eText;    eText.length = text.length;    char[26] temp;     foreach (i; 0..text.length) {        if (showSteps) writeln(left, ' ', right);        int index;        if (mode == Mode.ENCRYPT) {            index = right.indexOf(text[i]);            eText[i] = left[index];        } else {            index = left.indexOf(text[i]);            eText[i] = right[index];        }        if (i == text.length - 1) break;         // permute left         foreach (j; index..26) temp[j - index] = left[j];        foreach (j; 0..index) temp[26 - index + j] = left[j];        auto store = temp[1];        foreach (j; 2..14) temp[j - 1] = temp[j];        temp[13] = store;        left = temp.dup;         // permute right         foreach (j; index..26) temp[j - index] = right[j];        foreach (j; 0..index) temp[26 - index + j] = right[j];        store = temp[0];        foreach (j; 1..26) temp[j - 1] = temp[j];        temp[25] = store;        store = temp[2];        foreach (j; 3..14) temp[j - 1] = temp[j];        temp[13] = store;        right = temp.dup;    }     return eText.idup;} void main() {    auto plainText = "WELLDONEISBETTERTHANWELLSAID";    writeln("The original plaintext is : ", plainText);    writeln("\nThe left and right alphabets after each permutation during encryption are :\n");    auto cipherText = exec(plainText, Mode.ENCRYPT, true);    writeln("\nThe ciphertext is : ", cipherText);    auto plainText2 = exec(cipherText, Mode.DECRYPT);    writeln("\nThe recovered plaintext is : ", plainText2);}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :

HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

## Delphi

Translation of: Kotlin
` program Chaocipher; {\$APPTYPE CONSOLE} uses  System.SysUtils; type  TMode = (mcEncrypt, mcDecrypt); const  lAlphabet = 'HXUCZVAMDSLKPEFJRIGTWOBNYQ';  rAlphabet = 'PTLNBQDEOYSFAVZKGJRIHWXUMC'; function Chao(text: AnsiString; Mode: TMode; showSteps: boolean): AnsiString;begin  var len := Length(text);   var left: AnsiString := lAlphabet;  var right: AnsiString := rAlphabet;   var eText: AnsiString;  SetLength(eText, len);  var temp: AnsiString;  SetLength(temp, 26);   for var i := 0 to len - 1 do  begin    if showSteps then      writeln(left, ' ', right);     var index := 0;     if Mode = mcEncrypt then    begin      index := pos(text[i + 1], right) - 1;      eText[i + 1] := left[index + 1];    end    else    begin      index := pos(text[i + 1], left) - 1;      eText[i + 1] := right[index + 1];    end;     if i = len - 1 then      Break;     // premute left    for var j := index to 25 do      temp[j - index + 1] := left[j + 1];     for var j := 0 to index - 1 do      temp[27 - index + j] := left[j + 1];    var store := temp[2];     for var j := 2 to 13 do      temp[j] := temp[j + 1];     temp[14] := store;     left := temp;     // permute right    for var j := index to 25 do      temp[j - index + 1] := right[j + 1];     for var j := 0 to index - 1 do      temp[27 - index + j] := right[j + 1];     store := temp[0 + 1];     for var j := 1 to 25 do      temp[j] := temp[j + 1];     temp[26] := store;    store := temp[3];     for var j := 3 to 13 do      temp[j] := temp[j + 1];     temp[14] := store;     right := temp;  end;  Result := eText;end; begin  var plainText := 'WELLDONEISBETTERTHANWELLSAID';  writeln('The original plaintext is :', plainText);  write(#10'The left and right alphabets after each permutation ');  writeln('during encryption are :'#10);  var cipherText := Chao(plainText, mcEncrypt, true);  writeln(#10'The ciphertext is :', cipherText);  var plainText2 := Chao(cipherText, mcDecrypt, false);  writeln(#10'The recovered plaintext is : ', plainText2);  readln;end.`

## F#

### The Functions

` // Implement Chaocipher. Nigel Galloway: July 13th., 2019let pL n=function g when g=n->0 |g when g=(n+1)%26->13 |g->let x=(25+g-n)%26 in if x<13 then x else x+1let pR n=function g when g=n->25 |g when g=(n+3)%26->13 |g when g=(n+1)%26->0 |g when g=(n+2)%26->1 |g->let x=(24+g-n)%26 in if x<13 then x else x+1let encrypt lW rW txt=Array.scan(fun (lW,rW) t->let n=Array.findIndex(fun n->n=t) rW in ((Array.permute(pL n) lW,(Array.permute(pR n) rW))))(lW,rW) txt                        |>Array.skip 1|>Array.map(fun(n,_)->n.[0])|>System.Stringlet decrypt lW rW txt=Array.scan(fun (_,lW,rW) t->let n=Array.findIndex(fun n->n=t) lW in ((Array.item n rW,Array.permute(pL n) lW,(Array.permute(pR n) rW))))('0',lW,rW) txt                        |>Array.skip 1|>Array.map(fun(n,_,_)->n)|>System.String `

` printfn "%s" (encrypt ("HXUCZVAMDSLKPEFJRIGTWOBNYQ".ToCharArray()) ("PTLNBQDEOYSFAVZKGJRIHWXUMC".ToCharArray()) ("WELLDONEISBETTERTHANWELLSAID".ToCharArray()))printfn "%s" (decrypt ("HXUCZVAMDSLKPEFJRIGTWOBNYQ".ToCharArray()) ("PTLNBQDEOYSFAVZKGJRIHWXUMC".ToCharArray()) ("OAHQHCNYNXTSZJRRHJBYHQKSOUJY".ToCharArray())) `
Output:
```OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID
```

## Factor

`USING: arrays combinators fry io kernel locals math namespacesprettyprint sequences sequences.extras strings ;IN: rosetta-code.chaocipher CONSTANT: zenith 0CONSTANT: nadir  13 SYMBOLS: l-alphabet r-alphabet last-index ; : init-alphabets ( -- )    "HXUCZVAMDSLKPEFJRIGTWOBNYQ" l-alphabet    "PTLNBQDEOYSFAVZKGJRIHWXUMC" r-alphabet [ set ] [email protected] ; : zero-alphabet ( seq -- seq' )    last-index get rotate ; : 3append ( a b c d -- abcd )    append append append ; :: permute-l-alphabet ( -- )    l-alphabet get zero-alphabet dup    zenith 1 + swap nth :> extracted-char    {        [ 1 head ]        [ nadir 1 + head 2 tail ]        [ drop extracted-char 1string ]        [ nadir 1 + tail ]    } cleave    3append l-alphabet set ; :: permute-r-alphabet ( -- )    r-alphabet get zero-alphabet    1 rotate dup    zenith 2 + swap nth :> extracted-char    {        [ 2 head ]        [ nadir 1 + head 3 tail ]        [ drop extracted-char 1string ]        [ nadir 1 + tail ]    } cleave    3append r-alphabet set ; : encipher-char ( char alpha1 alpha2 -- char' )    '[ _ get index dup last-index set _ get nth ] call ; : encipher ( str quot -- str' )    [ permute-l-alphabet permute-r-alphabet ] compose map    init-alphabets ; inline : encrypt ( str -- str' )    [ r-alphabet l-alphabet encipher-char ] encipher ; : decrypt ( str -- str' )    [ l-alphabet r-alphabet encipher-char ] encipher ; : main ( -- )    init-alphabets    "WELLDONEISBETTERTHANWELLSAID" encrypt dup decrypt    [ print ] [email protected] ; MAIN: main`
Output:
```OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID
```

## Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.

## Go

Translation of: Kotlin
`package main import(    "fmt"    "strings"    "unicode/utf8") type Mode int const(    Encrypt Mode = iota    Decrypt) const(    lAlphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"    rAlphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC") func Chao(text string, mode Mode, showSteps bool) string {    len := len(text)    if utf8.RuneCountInString(text) != len {        fmt.Println("Text contains non-ASCII characters")        return ""    }    left  := lAlphabet    right := rAlphabet    eText := make([]byte, len)    temp  := make([]byte, 26)     for i := 0; i < len; i++ {        if showSteps {            fmt.Println(left, " ", right)        }        var index int        if mode == Encrypt {            index = strings.IndexByte(right, text[i])            eText[i] = left[index]        } else {            index = strings.IndexByte(left, text[i])            eText[i] = right[index]        }        if i == len - 1 {            break        }         // permute left        for j := index; j < 26; j++ {            temp[j - index] = left[j]        }        for j := 0; j < index; j++ {            temp[26 - index + j] = left[j]        }        store := temp[1]        for j := 2; j < 14; j++ {            temp[j - 1] = temp[j]        }        temp[13] = store        left = string(temp[:])         // permute right         for j := index; j < 26; j++ {            temp[j - index] = right[j]        }        for j := 0; j < index; j++ {            temp[26 - index + j] = right[j]        }        store = temp[0]        for j := 1; j < 26; j++ {            temp[j - 1] = temp[j]        }        temp[25] = store        store = temp[2]        for j := 3; j < 14; j++ {            temp[j - 1] = temp[j]        }        temp[13] = store        right = string(temp[:])    }     return string(eText[:])} func main() {    plainText := "WELLDONEISBETTERTHANWELLSAID"    fmt.Println("The original plaintext is :", plainText)    fmt.Print("\nThe left and right alphabets after each permutation ")    fmt.Println("during encryption are :\n")    cipherText := Chao(plainText, Encrypt, true)    fmt.Println("\nThe ciphertext is :",  cipherText)    plainText2 := Chao(cipherText, Decrypt, false)    fmt.Println("\nThe recovered plaintext is :", plainText2)}`
Output:
```Same as Kotlin entry.
```

## Groovy

Translation of: Java
`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) {                println("\${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            }             // permute left             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)             // permute right             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)    }     static void main(String[] args) {        String plainText = "WELLDONEISBETTERTHANWELLSAID"        println("The original plaintext is : \$plainText")        println("\nThe left and right alphabets after each permutation during encryption are:")        String cipherText = exec(plainText, Mode.ENCRYPT, true)        println("\nThe cipher text is : \$cipherText")        String plainText2 = exec(cipherText, Mode.DECRYPT)        println("\nThe recovered plaintext is : \$plainText2")    }}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are:
HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ  YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY  LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF  MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD  VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE  HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX  RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON  SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS  NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR  NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW  WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP  GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF  OBMESWKYZXUCPRTLNHFAGVQDJI

The cipher text is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

`import Data.List (elemIndex) chao  :: Eq a  => [a] -> [a] -> Bool -> [a] -> [a]chao _ _ _ [] = []chao l r plain (x:xs) = maybe [] go (elemIndex x src)  where    (src, dst)      | plain = (l, r)      | otherwise = (r, l)    go n =      dst !! n :      chao        (shifted 1 14 (rotated n l))        ((shifted 2 14 . shifted 0 26) (rotated n r))        plain        xs rotated :: Int -> [a] -> [a]rotated n = take . length <*> drop n . cycle shifted :: Int -> Int -> [a] -> [a]shifted src dst s = concat [x, rotated 1 y, b]  where    (a, b) = splitAt dst s    (x, y) = splitAt src a encode = False decode = True main :: IO ()main = do  let chaoWheels =        chao "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC"      plainText = "WELLDONEISBETTERTHANWELLSAID"      cipherText = chaoWheels encode plainText  print plainText  print cipherText  print \$ chaoWheels decode cipherText`
Output:
```"WELLDONEISBETTERTHANWELLSAID"
"OAHQHCNYNXTSZJRRHJBYHQKSOUJY"
"WELLDONEISBETTERTHANWELLSAID"```

## Java

Translation of: Kotlin
`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;            }             // permute left             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);             // permute right             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);    }}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are:
HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ  YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY  LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF  MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD  VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE  HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX  RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON  SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS  NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR  NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW  WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP  GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF  OBMESWKYZXUCPRTLNHFAGVQDJI

The cipher text is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

## J

Translation of: Raku
`reset =:  verb define  LEFT  =:  'HXUCZVAMDSLKPEFJRIGTWOBNYQ'  RIGHT =:  'PTLNBQDEOYSFAVZKGJRIHWXUMC') enc =:  verb define  z =.  LEFT  {~ i =. RIGHT i. y  permute {. i  z) dec =:  verb define  z =.  RIGHT {~ i =. LEFT i. y  permute {. i  z) permute =: verb define  LEFT  =:  LEFT  |.~ - y  LEFT  =:  (1 |. 13 {. LEFT) , 13 }. LEFT   RIGHT =:  RIGHT |.~ - y + 1  RIGHT =:  ({. RIGHT) , (1 |. RIGHT {~ 2+i.12) , 13 }. RIGHT) chao =:  enc :. dec reset ''smoutput E =.  chao 'WELLDONEISBETTERTHANWELLSAID'reset ''smoutput D =.  chao^:_1 E`
Output:
```OMUUADCMTLZMXXMGXWPCOMUULPTA
WELLDONEISBETTERTHANWELLSAID
```

## JavaScript

Translation of: C

Script source

`const L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";const R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC"; const ENCRYPT = 0;const DECRYPT = 1; function setCharAt(str, index, chr) {    if (index > str.length - 1) return str;    return str.substr(0, index) + chr + str.substr(index + 1);} function chao(text, mode, show_steps) {    var left = L_ALPHABET;    var right = R_ALPHABET;    var out = text;    var temp = "01234567890123456789012345";    var i = 0;    var index, j, store;     if (show_steps) {        console.log("The left and right alphabets after each permutation during encryption are :");    }    while (i < text.length) {        if (show_steps) {            console.log(left + "  " + right);        }        if (mode == ENCRYPT) {            index = right.indexOf(text[i]);            out = setCharAt(out, i, left[index]);        } else {            index = left.indexOf(text[i]);            out = setCharAt(out, i, right[index]);        }        if (i == text.length - 1) {            break;        }         //permute left        j = index;        while (j < 26) {            temp = setCharAt(temp, j - index, left[j])            j += 1;        }        j = 0;        while (j < index) {            temp = setCharAt(temp, 26 - index + j, left[j]);            j += 1;        }        store = temp[1];        j = 2;        while (j < 14) {            temp = setCharAt(temp, j - 1, temp[j]);            j += 1;        }        temp = setCharAt(temp, 13, store);        left = temp;         //permute right        j = index;        while (j < 26) {            temp = setCharAt(temp, j - index, right[j]);            j += 1;        }        j = 0;        while (j < index) {            temp = setCharAt(temp, 26 - index + j, right[j]);            j += 1;        }        store = temp[0];        j = 1;        while (j < 26) {            temp = setCharAt(temp, j - 1, temp[j]);            j += 1;        }        temp = setCharAt(temp, 25, store);        store = temp[2];        j = 3;        while (j < 14) {            temp = setCharAt(temp, j - 1, temp[j]);            j += 1;        }        temp = setCharAt(temp, 13, store);        right = temp;         i += 1;    }     return out;} function main() {    var out = document.getElementById("content");    const plain_text = "WELLDONEISBETTERTHANWELLSAID";     out.innerHTML = "<p>The original plaintext is : " + plain_text + "</p>";    var cipher_text = chao(plain_text, ENCRYPT, true);    out.innerHTML += "<p>The ciphertext is : " + cipher_text + "</p>";    var decipher_text = chao(cipher_text, DECRYPT, false);    out.innerHTML += "<p>The recovered plaintext is : " + decipher_text + "</p>";}`

Solution page

`<!DOCTYPE html><html>    <head>        <title>Chaocipher</title>        <script src="chaocipher.js"></script>    </head>    <body onload="main()">        <div id="content"></div>    </body></html>`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID
The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

## Julia

Modified from the Kotlin and Raku entries.

`const leftalphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"const rightalphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC" function chacocoding(text, encoding, verbose=false)    left, right = Vector{Char}(leftalphabet), Vector{Char}(rightalphabet)    len, coded = length(text), similar(Vector{Char}(text))    for i in 1:len        verbose && println(String(left), "   ", String(right))        n = indexin(text[i], encoding ? right : left)[1]        coded[i] = encoding ? left[n] : right[n]        if i < len            left .= circshift(left, -n + 1)            left[2:14] .= circshift(left[2:14], -1)            right .= circshift(right, -n)            right[3:14] .= circshift(right[3:14], -1)        end    end    String(coded)end function testchacocipher(txt)    println("The original plaintext is: \$txt")    println("\nThe left and right alphabets for each character during encryption are:")    encoded = chacocoding(txt, true, true)    println("\nThe encoded ciphertext is: \$encoded")    decoded = chacocoding(encoded, false)    println("\nDecoded, the recovered plaintext is: \$decoded")end testchacocipher("WELLDONEISBETTERTHANWELLSAID") `
Output:
```The original plaintext is: WELLDONEISBETTERTHANWELLSAID

The left and right alphabets for each character during encryption are:
HXUCZVAMDSLKPEFJRIGTWOBNYQ   PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW   XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ   LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF   LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ   RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ   YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY   LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF   MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD   VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE   HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX   RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON   SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS   NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR   NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW   WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP   GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF   OBMESWKYZXUCPRTLNHFAGVQDJI

The encoded ciphertext is: OAHQHCNYNXTSZJRRHJBYHQKSOUJY

Decoded, the recovered plaintext is: WELLDONEISBETTERTHANWELLSAID
```

## Kotlin

This is based on the C# implementation referred to in the task description, except that the encrypt and decrypt operations are combined into a single method.

`// Version 1.2.40 enum class Mode { ENCRYPT, DECRYPT } object Chao {    private val lAlphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"    private val rAlphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC"     fun exec(text: String, mode: Mode, showSteps: Boolean = false): String {        var left  = lAlphabet        var right = rAlphabet        val eText = CharArray(text.length)        val temp  = CharArray(26)         for (i in 0 until text.length) {            if (showSteps) println("\$left  \$right")            var index: Int            if (mode == Mode.ENCRYPT) {                index = right.indexOf(text[i])                eText[i] = left[index]            }            else {                index = left.indexOf(text[i])                eText[i] = right[index]            }            if (i == text.length - 1) break             // permute left             for (j in index..25) temp[j - index] = left[j]            for (j in 0 until index) temp[26 - index + j] = left[j]            var store = temp[1]            for (j in 2..13) temp[j - 1] = temp[j]            temp[13] = store            left = String(temp)             // permute right             for (j in index..25) temp[j - index] = right[j]            for (j in 0 until index) temp[26 - index + j] = right[j]            store = temp[0]            for (j in 1..25) temp[j - 1] = temp[j]            temp[25] = store            store = temp[2]            for (j in 3..13) temp[j - 1] = temp[j]            temp[13] = store            right = String(temp)        }         return String(eText)    }} fun main(args: Array<String>) {    val plainText = "WELLDONEISBETTERTHANWELLSAID"    println("The original plaintext is : \$plainText")    println("\nThe left and right alphabets after each permutation" +             " during encryption are :\n")    val cipherText = Chao.exec(plainText, Mode.ENCRYPT, true)    println("\nThe ciphertext is : \$cipherText")    val plainText2 = Chao.exec(cipherText, Mode.DECRYPT)    println("\nThe recovered plaintext is : \$plainText2")}`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :

HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ  YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY  LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF  MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD  VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE  HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX  RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON  SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS  NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR  NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW  WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP  GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF  OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
```

## Lua

`-- Chaocipher, in Lua, 6/19/2020 dblocal Chaocipher = {  ct = "HXUCZVAMDSLKPEFJRIGTWOBNYQ",  pt = "PTLNBQDEOYSFAVZKGJRIHWXUMC",  encrypt = function(self, text) return self:_encdec(text, true) end,  decrypt = function(self, text) return self:_encdec(text, false) end,  _encdec = function(self, text, encflag)    local ct, pt, s = self.ct, self.pt, ""    local cshl = function(s,i) return s:sub(i) .. s:sub(1,i-1) end    local sshl = function(s,i) return s:sub(1,i-1) .. s:sub(i+1,14) .. s:sub(i,i) .. s:sub(15) end    for ch in text:gmatch(".") do      local i = (encflag and pt or ct):find(ch)      s = s .. (encflag and ct or pt):sub(i,i)      if encflag then print(ct, pt, ct:sub(i,i), pt:sub(i,i)) end      ct, pt = sshl(cshl(ct, i), 2), sshl(cshl(pt, i+1), 3)    end    return s  end,}local plainText = "WELLDONEISBETTERTHANWELLSAID"local encryptText = Chaocipher:encrypt(plainText)local decryptText = Chaocipher:decrypt(encryptText)print()print("The original text was:  " .. plainText)print("The encrypted text is:  " .. encryptText)print("The decrypted text is:  " .. decryptText)`
Output:
```HXUCZVAMDSLKPEFJRIGTWOBNYQ      PTLNBQDEOYSFAVZKGJRIHWXUMC      O       W
ONYQHXUCZVAMDBSLKPEFJRIGTW      XUCPTLNBQDEOYMSFAVZKGJRIHW      A       E
ZILGMTONQXCVARDBSKWPEYHUFJ      LNBIMSAVKGQDJOERYHFWZXUCPT      J       T
JILGMTONQXCVAZRDBSKWPEYHUF      LNIMSAVKGQDJOBERYHFWZXUCPT      R       E
RBSKWPEYHUFJIDLGMTONQXCVAZ      RYFWZXUCPTLNIHMSAVKGQDJOBE      R       R
RSKWPEYHUFJIDBLGMTONQXCVAZ      YFZXUCPTLNIHMWSAVKGQDJOBER      H       T
HFJIDBLGMTONQUXCVAZRSKWPEY      LNHMWSAVKGQDJIOBERYFZXUCPT      J       H
JDBLGMTONQUXCIVAZRSKWPEYHF      MWAVKGQDJIOBESRYFZXUCPTLNH      B       A
BGMTONQUXCIVALZRSKWPEYHFJD      VKQDJIOBESRYFGZXUCPTLNHMWA      Y       N
YFJDBGMTONQUXHCIVALZRSKWPE      HMAVKQDJIOBESWRYFGZXUCPTLN      H       W
HIVALZRSKWPEYCFJDBGMTONQUX      RYGZXUCPTLNHMFAVKQDJIOBESW      Q       E
QXHIVALZRSKWPUEYCFJDBGMTON      SWYGZXUCPTLNHRMFAVKQDJIOBE      K       L
KPUEYCFJDBGMTWONQXHIVALZRS      NHMFAVKQDJIOBRESWYGZXUCPTL      S       L
SPUEYCFJDBGMTKWONQXHIVALZR      NHFAVKQDJIOBRMESWYGZXUCPTL      O       S
OQXHIVALZRSPUNEYCFJDBGMTKW      WYZXUCPTLNHFAGVKQDJIOBRMES      U       A
UEYCFJDBGMTKWNOQXHIVALZRSP      GVQDJIOBRMESWKYZXUCPTLNHFA      J       I
JBGMTKWNOQXHIDVALZRSPUEYCF      OBMESWKYZXUCPRTLNHFAGVQDJI      Y       D

The original text was:  WELLDONEISBETTERTHANWELLSAID
The encrypted text is:  OAHQHCNYNXTSZJRRHJBYHQKSOUJY
The decrypted text is:  WELLDONEISBETTERTHANWELLSAID```

## Mathematica/Wolfram Language

`ClearAll[ichaoalphabet, iMoveToFront, ChaoCipher]ichaoalphabet = CharacterRange["A", "Z"];iMoveToFront[l_List, sel_] := Module[{p},  p = FirstPosition[l, sel];  RotateLeft[l, p - 1]  ]ChaoCipher::wrongcipheralpha =   "The cipher alphabet `1` is not a permutation of \\"A\"\[LongDash]\"Z\".";ChaoCipher::wrongplainalpha =   "The plain alphabet `1` is not a permutation of \"A\"\[LongDash]\"Z\\".";ChaoCipher[str_String, {plainalpha_List, cipheralpha_List}] :=  Module[{pa, ca, plain, new, papermute, capermute, out},  ca = ToUpperCase[cipheralpha];  pa = ToUpperCase[plainalpha];  If[Sort[ca] =!= Sort[ichaoalphabet],   Message[ChaoCipher::wrongcipheralpha, ca];   \$Failed   ,   If[Sort[pa] =!= Sort[ichaoalphabet],    Message[ChaoCipher::wrongplainalpha, pa];    \$Failed    ,    capermute = SubsetMap[RotateLeft, Range[26], Range[2, 14]];    papermute =      SubsetMap[RotateLeft, RotateLeft[Range[26], 1], Range[3, 14]];    plain =      Select[Characters[ToUpperCase[str]], MemberQ[ichaoalphabet, #] &];     out = Table[      new = Association[Thread[pa -> ca]][p];      pa = iMoveToFront[pa, p];      ca = iMoveToFront[ca, new];      pa = pa[[papermute]];      ca = ca[[capermute]];      new      ,      {p, plain}      ];    StringJoin[out]    ]   ]  ]ChaoCipher["WELLDONEISBETTERTHANWELLSAID",{[email protected]"PTLNBQDEOYSFAVZKGJRIHWXUMC",[email protected]"HXUCZVAMDSLKPEFJRIGTWOBNYQ"}] `
Output:
`OAHQHCNYNXTSZJRRHJBYHQKSOUJY`

## Nim

Translation of: Kotlin
`import strformat type  Mode = enum    Encrypt    Decrypt const lAlphabet: string = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"const rAlphabet: string = "PTLNBQDEOYSFAVZKGJRIHWXUMC" proc chao(text: string, mode: Mode, verbose: bool = false): string =  var left = lAlphabet  var right = rAlphabet  var eText = newSeq[char](text.len)  var temp: array[26, char]   for i in 0..<text.len:    if verbose:      echo &"{left}  {right}"    var index: int    if mode == Encrypt:      index = right.find(text[i])      eText[i] = left[index]    else:      index = left.find(text[i])      eText[i] = right[index]    if (i == text.len - 1):      break     # permute left    for j in index..25:      temp[j - index] = left[j]    for j in 0..<index:      temp[26 - index + j] = left[j]    var store = temp[1]    for j in 2..13:      temp[j - 1] = temp[j]    temp[13] = store    left = ""    for i in temp:      left &= \$i     # permute right    for j in index..25:      temp[j - index] = right[j]    for j in 0..<index:      temp[26 - index + j] = right[j]    store = temp[0]    for j in 1..25:      temp[j - 1] = temp[j]    temp[25] = store    store = temp[2]    for j in 3..13:      temp[j - 1] = temp[j]    temp[13] = store    right = ""    for i in temp:      right &= \$i   for i in eText:    result &= \$i var plainText = "WELLDONEISBETTERTHANWELLSAID"echo &"The original plaintext is: {plainText}"echo "\nThe left and right alphabets after each permutation during encryption are:\n"var cipherText = chao(plainText, Encrypt, true)echo &"\nThe ciphertext is: {cipherText}"var plainText2 = chao(cipherText, Decrypt, false)echo &"\nThe recovered plaintext is: {plainText2}"`
Output:
```The original plaintext is: WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are:

HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ  YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY  LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF  MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD  VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE  HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX  RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON  SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS  NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR  NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW  WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP  GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF  OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is: OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is: WELLDONEISBETTERTHANWELLSAID
```

### Another implementation

Using functions from the stdlib instead of manual array manipulations:

`import std/[algorithm, strutils] type  Mode = enum    Encrypt    Decrypt const  lAlphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"  rAlphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC" proc chao(text: string; mode: Mode; verbose = false): string =  var    left = lAlphabet    right = rAlphabet    eText = newSeq[char](text.len)   for i in 0 ..< text.len:    if verbose:      echo left, "  ", right    var index: int    if mode == Encrypt:      index = right.find(text[i])      eText[i] = left[index]    else:      index = left.find(text[i])      eText[i] = right[index]    if i == text.len - 1:      break     # permute left    left.rotateLeft(index)    left.rotateLeft(1..13, 1)     # permute right    right.rotateLeft(index + 1)    right.rotateLeft(2..13, 1)   result = eText.join() let plainText = "WELLDONEISBETTERTHANWELLSAID"echo "The original plaintext is: ", plainTextecho "\nThe left and right alphabets after each permutation during encryption are:\n"let cipherText = chao(plainText, Encrypt, true)echo "\nThe ciphertext is: ", cipherTextlet plainText2 = chao(cipherText, Decrypt, false)echo "\nThe recovered plaintext is: ", plainText2`

Same output as above.

## Objeck

Translation of: Kotlin
`class Chaocipher {  L_ALPHABET : static : Char[];  R_ALPHABET : static : Char[];   function : Main(args : String[]) ~ Nil {    L_ALPHABET := "HXUCZVAMDSLKPEFJRIGTWOBNYQ"->ToCharArray();    R_ALPHABET := "PTLNBQDEOYSFAVZKGJRIHWXUMC"->ToCharArray();    plainText := "WELLDONEISBETTERTHANWELLSAID"->ToCharArray();     System.IO.Console->Print("The original plaintext is: ")->PrintLine(plainText);    "\nThe left and right alphabets after each permutation during encryption are:\n"->PrintLine();    cipherText := Chao(plainText, Mode->ENCRYPT, true);    System.IO.Console->Print("\nThe ciphertext is: ")->PrintLine(cipherText);    plainText2 := Chao(cipherText, Mode->DECRYPT, false);    System.IO.Console->Print("The recovered plaintext is: ")->PrintLine(plainText2);  }   function : Chao(in : Char[], mode : Mode, show_steps : Bool) ~ Char[] {      i : Int; j : Int; index : Int;    store : Char;    len := in->Size();    left := Char->New[26];   right := Char->New[26]; temp := Char->New[26];    eText := Char->New[len];     Runtime->Copy(left, 0, L_ALPHABET, 0, L_ALPHABET->Size());    Runtime->Copy(right, 0, R_ALPHABET, 0, R_ALPHABET->Size());     for(i := 0; i < len; i += 1;) {      if (show_steps) {        System.IO.Console->Print(left)->Print(' ')->PrintLine(right);      };      if (mode = Mode->ENCRYPT) {        index := IndexOf(right, in[i]);        eText[i] := left[index];      }      else {        index := IndexOf(left, in[i]);        eText[i] := right[index];      };       if (i = len - 1) {        break;      };       # left      for(j := index; j < 26; j += 1;) { temp[j - index] := left[j]; };      for(j :=0; j < index; j += 1;) { temp[26 - index + j] := left[j]; };      store := temp[1];      for(j := 2; j < 14; j += 1;) { temp[j - 1] := temp[j]; };      temp[13] := store;      Runtime->Copy(left, 0, temp, 0, temp->Size());       # right      for(j := index; j < 26; j += 1;) { temp[j - index] := right[j]; };      for(j :=0; j < index; j += 1;) { temp[26 - index + j] := right[j]; };      store := temp[0];      for(j :=1; j < 26; j += 1;) { temp[j - 1] := temp[j]; };          temp[25] := store;          store := temp[2];          for(j := 3; j < 14; j += 1;) { temp[j - 1] := temp[j]; };          temp[13] := store;          Runtime->Copy(right, 0, temp, 0, temp->Size());    };     return eText;  }   function : IndexOf(str : Char[], c : Char) ~ Int {    for(i := 0; i < str->Size(); i += 1;) {      if(c = str[i]) {        return i;      };    };     return -1;  }   enum Mode { ENCRYPT, DECRYPT }  }`
Output:
```The original plaintext is: WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are:

HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is: OAHQHCNYNXTSZJRRHJBYHQKSOUJY
The recovered plaintext is: WELLDONEISBETTERTHANWELLSAID
```

## Perl

Translation of: Raku

Since rotate is not a built-in in Perl, using a custom one, not general-purpose but sufficient for this task.

`sub init {    @left  = split '', 'HXUCZVAMDSLKPEFJRIGTWOBNYQ';    @right = split '', 'PTLNBQDEOYSFAVZKGJRIHWXUMC';} sub encode {    my(\$letter) = @_;    my \$index = index join('', @right), \$letter;    my \$enc   = \$left[\$index];    left_permute(\$index);    right_permute(\$index);    \$enc} sub decode {    my(\$letter) = @_;    my \$index = index join('', @left), \$letter;    my \$dec   = \$right[\$index];    left_permute(\$index);    right_permute(\$index);    \$dec} sub right_permute {    my(\$index) = @_;    rotate(\@right, \$index + 1);    rotate(\@right, 1, 2, 13);} sub left_permute {    my(\$index) = @_;    rotate(\@left, \$index);    rotate(\@left, 1, 1, 13);} sub rotate {    our @list; local *list = shift;    my(\$n,\$s,\$e) = @_;    @list = \$s ? @list[0..\$s-1, \$s+\$n..\$e+\$n-1, \$s..\$s+\$n-1, \$e+1..\$#list]               : @list[\$n..\$#list, 0..\$n-1]} init; \$e_msg .= encode(\$_) for split '', 'WELLDONEISBETTERTHANWELLSAID';init; \$d_msg .= decode(\$_) for split '', \$e_msg; print "\$e_msg\n";print "\$d_msg\n";`
Output:
```OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID```

## Phix

Originally translated from C, but ended up more of a direct implementation of the algorithm in the pdf.

`-- demo\rosetta\Chao_cipher.exwconstant l_alphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ",         r_alphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC" enum ENCRYPT, DECRYPT function chao_cipher(string in, integer mode, bool show_steps)    integer len = length(in)    string out = repeat(' ',len)    string left = l_alphabet,           right = r_alphabet    for i=1 to len do        if show_steps then printf(1,"%s  %s\n", {left, right}) end if        integer index = find(in[i],iff(mode==ENCRYPT?right:left))        out[i] = iff(mode==ENCRYPT?left:right)[index]         if i==len then exit end if         /* permute left */        left = left[index..26]&left[1..index-1]        left[2..14] = left[3..14]&left[2]         /* permute right */        right = right[index+1..26]&right[1..index]        right[3..14] = right[4..14]&right[3]    end for    return outend function string plain_text = "WELLDONEISBETTERTHANWELLSAID"printf(1,"The original plaintext is : %s\n", {plain_text}) --printf(1,"\nThe left and right alphabets after each permutation"&--         " during encryption are :\n\n")--string cipher_text = chao_cipher(plain_text, ENCRYPT, true)string cipher_text = chao_cipher(plain_text, ENCRYPT, false)printf(1,"\nThe ciphertext is : %s\n", {cipher_text}) string plain_text2 = chao_cipher(cipher_text, DECRYPT, false)printf(1,"\nThe recovered plaintext is : %s\n", {plain_text2})`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
```

## Python

### Procedural

`# Python3 implementation of Chaocipher # left wheel = ciphertext wheel# right wheel = plaintext wheel def main():    # letters only! makealpha(key) helps generate lalpha/ralpha.     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):    # LEFT = cipher wheel     # Cycle second[1] through nadir[14] forward    lalph = list(lalph)    lalph = "".join([*lalph[0],                    *lalph[2:14],                    lalph[1],                    *lalph[14:]])     # RIGHT = plain wheel                        # Send the zenith[0] character to the end[25],    # cycle third[2] through nadir[14] characters forward    ralph = list(ralph)    ralph = "".join([*ralph[1:3],                     *ralph[4:15],                     ralph[3],                     *ralph[15:],                     ralph[0]])    return lalph, ralph main()`
```L: HXUCZVAMDSLKPEFJRIGTWOBNYQ
R: PTLNBQDEOYSFAVZKGJRIHWXUMC
I: WELLDONEISBETTERTHANWELLSAID
O: OAHQHCNYNXTSZJRRHJBYHQKSOUJY

======================================================
left:                     right:
======================================================
HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC

ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI
YFJBGMTKWNOQXCHIDVALZRSPUE JIBMESWKYZXUCOPRTLNHFAGVQD

OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID```

### Functional

Works with: Python version 3.7
`'''Chaocipher''' from itertools import chain, cycle, islice  # chao :: String -> String -> Bool -> String -> Stringdef chao(l):    '''Chaocipher encoding or decoding for the given       left and right 'wheels'.       A ciphertext is returned if the boolean flag       is True, and a plaintext if the flag is False.    '''    def go(l, r, plain, xxs):        if xxs:            (src, dst) = (l, r) if plain else (r, l)            (x, xs) = (xxs[0], xxs[1:])             def chaoProcess(n):                return [dst[n]] + go(                    shifted(1)(14)(rotated(n, l)),                    compose(shifted(2)(14))(shifted(0)(26))(                        rotated(n, r)                    ),                    plain,                    xs                )             return maybe('')(chaoProcess)(                elemIndex(x)(src)            )        else:            return []    return lambda r: lambda plain: lambda xxs: concat(go(        l, r, plain, xxs    ))  # rotated :: Int -> [a] -> [a]def rotated(z, s):    '''Rotation of string s by z characters.'''    return take(len(s))(        drop(z)(            cycle(s)        )    )  # shifted :: Int -> Int -> [a] -> [a]def shifted(src):    '''The string s with a set of its characters cyclically       shifted from a source index to a destination index.    '''    def go(dst, s):        (a, b) = splitAt(dst)(s)        (x, y) = splitAt(src)(a)        return concat([x, rotated(1, y), b])    return lambda dst: lambda s: go(dst, s)  # TEST ----------------------------------------------------# main :: IO ()def main():    '''Print the plain text, followed by       a corresponding cipher text,       and a decode of that cipher text.    '''    chaoWheels = chao(        "HXUCZVAMDSLKPEFJRIGTWOBNYQ"    )(        "PTLNBQDEOYSFAVZKGJRIHWXUMC"    )    plainText = "WELLDONEISBETTERTHANWELLSAID"    cipherText = chaoWheels(False)(plainText)     print(plainText)    print(cipherText)    print(        chaoWheels(True)(cipherText)    )  # GENERIC ------------------------------------------------- # Just :: a -> Maybe adef Just(x):    '''Constructor for an inhabited Maybe (option type) value.       Wrapper containing the result of a computation.    '''    return {'type': 'Maybe', 'Nothing': False, 'Just': x}  # Nothing :: Maybe adef Nothing():    '''Constructor for an empty Maybe (option type) value.       Empty wrapper returned where a computation is not possible.    '''    return {'type': 'Maybe', 'Nothing': True}  # compose (<<<) :: (b -> c) -> (a -> b) -> a -> cdef compose(g):    '''Right to left function composition.'''    return lambda f: lambda x: g(f(x))  # concat :: [[a]] -> [a]# concat :: [String] -> Stringdef concat(xs):    '''The concatenation of all the elements       in a list or iterable.    '''    def f(ys):        zs = list(chain(*ys))        return ''.join(zs) if isinstance(ys[0], str) else zs     return (        f(xs) if isinstance(xs, list) else (            chain.from_iterable(xs)        )    ) if xs else []  # drop :: Int -> [a] -> [a]# drop :: Int -> String -> Stringdef drop(n):    '''The sublist of xs beginning at       (zero-based) index n.    '''    def go(xs):        if isinstance(xs, (list, tuple, str)):            return xs[n:]        else:            take(n)(xs)            return xs    return lambda xs: go(xs)  # elemIndex :: Eq a => a -> [a] -> Maybe Intdef elemIndex(x):    '''Just the index of the first element in xs       which is equal to x,       or Nothing if there is no such element.    '''    def go(xs):        try:            return Just(xs.index(x))        except ValueError:            return Nothing()    return lambda xs: go(xs)  # maybe :: b -> (a -> b) -> Maybe a -> bdef maybe(v):    '''Either the default value v, if m is Nothing,       or the application of f to x,       where m is Just(x).    '''    return lambda f: lambda m: v if None is m or m.get('Nothing') else (        f(m.get('Just'))    )  # splitAt :: Int -> [a] -> ([a], [a])def splitAt(n):    '''A tuple pairing the prefix of length n       with the rest of xs.    '''    return lambda xs: (xs[0:n], xs[n:])  # take :: Int -> [a] -> [a]# take :: Int -> String -> Stringdef take(n):    '''The prefix of xs of length n,       or xs itself if n > length xs.    '''    return lambda xs: (        xs[0:n]        if isinstance(xs, (list, tuple))        else list(islice(xs, n))    )  # MAIN ---if __name__ == '__main__':    main()`
Output:
```WELLDONEISBETTERTHANWELLSAID
OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID```

## Raku

(formerly Perl 6)

Works with: Rakudo version 2018.03
`my @left;my @right; sub reset {    @left  = <HXUCZVAMDSLKPEFJRIGTWOBNYQ>.comb;    @right = <PTLNBQDEOYSFAVZKGJRIHWXUMC>.comb;} sub encode (\$letter) {    my \$index = @right.first: \$letter.uc, :k;    my \$enc   = @left[\$index];    \$index.&permute;    \$enc} sub decode (\$letter) {    my \$index = @left.first: \$letter.uc, :k;    my \$dec   = @right[\$index];    \$index.&permute;    \$dec} sub permute (\$index) {    @left.=rotate: \$index;    @left[1..13].=rotate;    @right.=rotate: \$index + 1;    @right[2..13].=rotate;} reset;say 'WELLDONEISBETTERTHANWELLSAID'.comb».&encode.join;reset;say 'OAHQHCNYNXTSZJRRHJBYHQKSOUJY'.comb».&decode.join;`
Output:
```OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID```

## Ruby

`txt    = "WELLDONEISBETTERTHANWELLSAID"@left  = "HXUCZVAMDSLKPEFJRIGTWOBNYQ".chars@right = "PTLNBQDEOYSFAVZKGJRIHWXUMC".chars def encrypt(char)  coded_char = @left[@right.index(char)]   @left.rotate!(@left.index(coded_char))  part = @left.slice!(1,13).rotate  @left.insert(1, *part)   @right.rotate!(@right.index(char)+1)  part = @right.slice!(2,12).rotate  @right.insert(2, *part)   @left[0]end puts txt.each_char.map{|c| encrypt(c) }.join  `
Output:
```OAHQHCNYNXTSZJRRHJBYHQKSOUJY
```

## Rust

`const LEFT_ALPHABET_CT: &str = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";const RIGHT_ALPHABET_PT: &str = "PTLNBQDEOYSFAVZKGJRIHWXUMC";const ZENITH: usize = 0;const NADIR: usize = 12;const SEQUENCE: &str = "WELLDONEISBETTERTHANWELLSAID"; fn cipher(letter: &char, left: &String, right: &String) -> (usize, char) {    let pos = right.find(*letter).unwrap();    let cipher = left.chars().nth(pos).unwrap();    (pos, cipher)} fn main() {    let mut left = LEFT_ALPHABET_CT.to_string();    let mut right = RIGHT_ALPHABET_PT.to_string();     let ciphertext = SEQUENCE.chars()        .map(|letter| {            let (pos, cipher_char) = cipher(&letter, &left, &right);            left = format!("{}{}", &left[pos..], &left[..pos]);            left = format!("{}{}{}{}", &left[ZENITH..1], &left[2..NADIR+2], &left[1..2], &left[NADIR+2..]);            if pos != right.len() - 1 {                right = format!("{}{}", &right[pos + 1..], &right[..pos + 1]);            }            right = format!("{}{}{}{}", &right[ZENITH..2], &right[3..NADIR+2], &right[2..3], &right[NADIR+2..]);            cipher_char        })        .collect::<String>();     println!("Plaintext: {}", SEQUENCE);    println!("Ciphertext: {}", ciphertext);}`
Output:
```Plaintext: WELLDONEISBETTERTHANWELLSAID
Ciphertext: OAHQHCNYNXTSZJRRHJBYHQKSOUJY```

## Tailspin

` templates chaocipher&{left:,right:,decode:}  templates permute    def ctshift: [ [email protected](\$..last)..., [email protected](1..\$-1)...];    def p1: \$ mod 26 + 1;    def ptshift: [ [email protected](\$p1..last)..., [email protected](1..\$p1-1)...];    ..|@chaocipher: { ct: [ \$ctshift(1), \$ctshift(3..14)..., \$ctshift(2), \$ctshift(15..last)...],      pt: [ \$ptshift(1..2)..., \$ptshift(4..14)..., \$ptshift(3), \$ptshift(15..last)...] };  end permute   @: {ct:[ \$left... ], pt: [ \$right... ], result:[]};  \$... -> #  '[email protected];' !   when <?(\$decode <=0>)> do    def plain: \$;    def index: [email protected] -> \[i](<=\$plain> \$i!\) -> \$(1);    ..|@.result: [email protected](\$index);    \$index -> permute -> !VOID  otherwise    def cipher: \$;    def index: [email protected] -> \[i](<=\$cipher> \$i!\) -> \$(1);    ..|@.result: [email protected](\$index);    \$index -> permute -> !VOIDend chaocipher 'WELLDONEISBETTERTHANWELLSAID' -> chaocipher&{left:'HXUCZVAMDSLKPEFJRIGTWOBNYQ', right:'PTLNBQDEOYSFAVZKGJRIHWXUMC',decode:0} -> '\$;' -> !OUT::write 'OAHQHCNYNXTSZJRRHJBYHQKSOUJY' -> chaocipher&{left:'HXUCZVAMDSLKPEFJRIGTWOBNYQ', right:'PTLNBQDEOYSFAVZKGJRIHWXUMC',decode:1} -> '\$;' -> !OUT::write `
Output:
```OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID
```

## Visual Basic .NET

Translation of: C#
`Module Module1     ReadOnly L_ALPHABET As String = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"    ReadOnly R_ALPHABET As String = "PTLNBQDEOYSFAVZKGJRIHWXUMC"     Enum Mode        ENCRYPT        DECRYPT    End Enum     Function Exec(text As String, mode As Mode, Optional showSteps As Boolean = False) As String        Dim left = L_ALPHABET.ToCharArray()        Dim right = R_ALPHABET.ToCharArray()        Dim eText(text.Length - 1) As Char        Dim temp(25) As Char         For i = 0 To text.Length - 1            If showSteps Then Console.WriteLine("{0} {1}", String.Join("", left), String.Join("", right))            Dim index As Integer            If mode = Mode.ENCRYPT Then                index = Array.IndexOf(right, text(i))                eText(i) = left(index)            Else                index = Array.IndexOf(left, text(i))                eText(i) = right(index)            End If            If i = text.Length - 1 Then Exit For             'permute left             For j = index To 25                temp(j - index) = left(j)            Next            For j = 0 To index - 1                temp(26 - index + j) = left(j)            Next            Dim store = temp(1)            For j = 2 To 13                temp(j - 1) = temp(j)            Next            temp(13) = store            temp.CopyTo(left, 0)             'permute right             For j = index To 25                temp(j - index) = right(j)            Next            For j = 0 To index - 1                temp(26 - index + j) = right(j)            Next            store = temp(0)            For j = 1 To 25                temp(j - 1) = temp(j)            Next            temp(25) = store            store = temp(2)            For j = 3 To 13                temp(j - 1) = temp(j)            Next            temp(13) = store            temp.CopyTo(right, 0)        Next         Return eText    End Function     Sub Main()        Dim plainText = "WELLDONEISBETTERTHANWELLSAID"        Console.WriteLine("The original plaintext is : {0}", plainText)        Console.WriteLine(vbNewLine + "The left and right alphabets after each permutation during encryption are :" + vbNewLine)        Dim cipherText = Exec(plainText, Mode.ENCRYPT, True)        Console.WriteLine(vbNewLine + "The ciphertext is : {0}", cipherText)        Dim plainText2 = Exec(cipherText, Mode.DECRYPT)        Console.WriteLine(vbNewLine + "The recovered plaintext is : {0}", plainText2)    End Sub End Module`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :

HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID```

## Wren

Translation of: Kotlin
`class Chao {    static encrypt { 0 }    static decrypt { 1 }     static exec(text, mode, showSteps) {        var len = text.count        if (len != text.bytes.count) Fiber.abort("Text contains non-ASCII characters.")        var left  = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"        var right = "PTLNBQDEOYSFAVZKGJRIHWXUMC"        var eText = List.filled(len, "")        var temp  = List.filled(26, "")        for (i in 0...len) {            if (showSteps) System.print("%(left)  %(right)")            var index            if (mode == Chao.encrypt) {                index = right.indexOf(text[i])                eText[i] = left[index]            } else {                index = left.indexOf(text[i])                eText[i] = right[index]            }            if (i == len - 1) break             // permute left            for (j in index..25) temp[j-index] = left[j]            for (j in 0...index) temp[26-index+j] = left[j]            var store = temp[1]            for (j in 2..13) temp[j-1] = temp[j]            temp[13] = store            left = temp.join()             // permute right            for (j in index..25) temp[j-index] = right[j]            for (j in 0...index) temp[26-index+j] = right[j]            store = temp[0]            for (j in 1..25) temp[j-1] = temp[j]            temp[25] = store            store = temp[2]            for (j in 3..13) temp[j-1] = temp[j]            temp[13] = store            right = temp.join()        }        return eText.join()    }} var plainText = "WELLDONEISBETTERTHANWELLSAID"System.print("The original plaintext is : %(plainText)")System.write("\nThe left and right alphabets after each permutation ")System.print("during encryption are :\n")var cipherText = Chao.exec(plainText, Chao.encrypt, true)System.print("\nThe ciphertext is : %(cipherText)")var plainText2 = Chao.exec(cipherText, Chao.decrypt, false)System.print("\nThe recovered plaintext is : %(plainText2)")`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are :

HXUCZVAMDSLKPEFJRIGTWOBNYQ  PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW  XUCPTLNBQDEOYMSFAVZKGJRIHW
ZILGMTONQXCVARDBSKWPEYHUFJ  LNBIMSAVKGQDJOERYHFWZXUCPT
JILGMTONQXCVAZRDBSKWPEYHUF  LNIMSAVKGQDJOBERYHFWZXUCPT
RBSKWPEYHUFJIDLGMTONQXCVAZ  RYFWZXUCPTLNIHMSAVKGQDJOBE
RSKWPEYHUFJIDBLGMTONQXCVAZ  YFZXUCPTLNIHMWSAVKGQDJOBER
HFJIDBLGMTONQUXCVAZRSKWPEY  LNHMWSAVKGQDJIOBERYFZXUCPT
JDBLGMTONQUXCIVAZRSKWPEYHF  MWAVKGQDJIOBESRYFZXUCPTLNH
BGMTONQUXCIVALZRSKWPEYHFJD  VKQDJIOBESRYFGZXUCPTLNHMWA
YFJDBGMTONQUXHCIVALZRSKWPE  HMAVKQDJIOBESWRYFGZXUCPTLN
HIVALZRSKWPEYCFJDBGMTONQUX  RYGZXUCPTLNHMFAVKQDJIOBESW
QXHIVALZRSKWPUEYCFJDBGMTON  SWYGZXUCPTLNHRMFAVKQDJIOBE
KPUEYCFJDBGMTWONQXHIVALZRS  NHMFAVKQDJIOBRESWYGZXUCPTL
SPUEYCFJDBGMTKWONQXHIVALZR  NHFAVKQDJIOBRMESWYGZXUCPTL
OQXHIVALZRSPUNEYCFJDBGMTKW  WYZXUCPTLNHFAGVKQDJIOBRMES
UEYCFJDBGMTKWNOQXHIVALZRSP  GVQDJIOBRMESWKYZXUCPTLNHFA
JBGMTKWNOQXHIDVALZRSPUEYCF  OBMESWKYZXUCPRTLNHFAGVQDJI

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
```

## zkl

Translation of: Raku
`class Chao{   var [const private] lAlphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ",		       rAlphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC";   fcn encode(text){ code(text,encodeL); }   fcn decode(text){ code(text,decodeL); }   // reset alphabets each [en|de]code and maintain re-entrancy   fcn code(text,f){ text.apply(f,Data(Void,lAlphabet),Data(Void,rAlphabet)) }   fcn [private] encodeL(letter,left,right){  // encode a letter      index:=right.index(letter);      enc  :=left[index].toChar();      permute(left,right,index);      println(left.text," ",right.text,"  ",index);      enc   }   fcn [private] decodeL(letter,left,right){  // decode a letter      index:=left.index(letter);      dec  :=right[index].toChar();      permute(left,right,index);      dec   }   fcn [private] permute(left,right,index){      left.append(left.pop(0,index));		// rotate index times      left.insert(13,left.pop(1));		// rotate [1..13] once       right.append(right.pop(0,index+1)); # rotate index+1 times, idx==25==noop      right.insert(13,right.pop(2));		// rotate [2..13] once   }}`
`plainText:="WELLDONEISBETTERTHANWELLSAID";println("The original plaintext is : ",plainText);println("\nThe left and right alphabets after each permutation"         " during encryption are:");cipherText:=Chao.encode(plainText);println("\nThe ciphertext is : ",cipherText); plainText2:=Chao.decode(cipherText);println("\nThe recovered plaintext is : ",plainText2);`
Output:
```The original plaintext is : WELLDONEISBETTERTHANWELLSAID

The left and right alphabets after each permutation during encryption are:
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW  21
ZILGMTONQXCVARDBSKWPEYHUFJ LNBIMSAVKGQDJOERYHFWZXUCPT  10
JILGMTONQXCVAZRDBSKWPEYHUF LNIMSAVKGQDJOBERYHFWZXUCPT  25
RBSKWPEYHUFJIDLGMTONQXCVAZ RYFWZXUCPTLNIHMSAVKGQDJOBE  14
RSKWPEYHUFJIDBLGMTONQXCVAZ YFZXUCPTLNIHMWSAVKGQDJOBER  0
HFJIDBLGMTONQUXCVAZRSKWPEY LNHMWSAVKGQDJIOBERYFZXUCPT  7
JDBLGMTONQUXCIVAZRSKWPEYHF MWAVKGQDJIOBESRYFZXUCPTLNH  2
BGMTONQUXCIVALZRSKWPEYHFJD VKQDJIOBESRYFGZXUCPTLNHMWA  2
YFJDBGMTONQUXHCIVALZRSKWPE HMAVKQDJIOBESWRYFGZXUCPTLN  21
HIVALZRSKWPEYCFJDBGMTONQUX RYGZXUCPTLNHMFAVKQDJIOBESW  13
QXHIVALZRSKWPUEYCFJDBGMTON SWYGZXUCPTLNHRMFAVKQDJIOBE  23
KPUEYCFJDBGMTWONQXHIVALZRS NHMFAVKQDJIOBRESWYGZXUCPTL  10
SPUEYCFJDBGMTKWONQXHIVALZR NHFAVKQDJIOBRMESWYGZXUCPTL  25
OQXHIVALZRSPUNEYCFJDBGMTKW WYZXUCPTLNHFAGVKQDJIOBRMES  15
UEYCFJDBGMTKWNOQXHIVALZRSP GVQDJIOBRMESWKYZXUCPTLNHFA  12
JBGMTKWNOQXHIDVALZRSPUEYCF OBMESWKYZXUCPRTLNHFAGVQDJI  5
YFJBGMTKWNOQXCHIDVALZRSPUE JIBMESWKYZXUCOPRTLNHFAGVQD  23

The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY

The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
```