Chaocipher: Difference between revisions

19,019 bytes added ,  2 months ago
Added Easylang
m (syntax highlighting fixup automation)
(Added Easylang)
 
(23 intermediate revisions by 11 users not shown)
Line 8:
 
;Task:
Code the algorithm in your language and to test that it works with the plaintext 'WELLDONEISBETTERTHANWELLSAID' used in the paper itself.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F correct_case(string)
R string.filter(s -> s.is_alpha()).map(s -> s.uppercase()).join(‘’)
 
Line 105 ⟶ 104:
YFJBGMTKWNOQXCHIDVALZRSPUE JIBMESWKYZXUCOPRTLNHFAGVQD
</pre>
 
=={{header|Ada}}==
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.
<syntaxhighlight lang=Ada"ada">
with Ada.Text_IO; use Ada.Text_IO;
 
Line 251 ⟶ 249:
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">-- Chaocipher algorithm by J.F.Byrne 1918.
on chaocipher(input, |key|, mode)
-- input: text to be enciphered or deciphered.
Line 378 ⟶ 375:
 
{{output}}
<syntaxhighlight lang="applescript">"Original text = WELLDONEISBETTERTHANWELLSAID
Enciphered = OAHQHCNYNXTSZJRRHJBYHQKSOUJY
Double enciphered = ZJVDGIXNNDNRHAXQUUJZGAFTANHW
De-double enciphered = OAHQHCNYNXTSZJRRHJBYHQKSOUJY
Deciphered = WELLDONEISBETTERTHANWELLSAID"</syntaxhighlight>
 
=={{header|Arc}}==
<syntaxhighlight lang="arc">(= lshift '((0 1) (2 14) (1 2) (14 26)))
(= rshift '((1 3) (4 15) (3 4) (15 26) (0 1)))
 
Line 423 ⟶ 419:
 
{{output}}
<syntaxhighlight lang="arc">
arc> (chaocipher "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC"
"WELLDONEISBETTERTHANWELLSAID")
Line 458 ⟶ 454:
"OAHQHCNYNXTSZJRRHJBYHQKSOUJY"
</syntaxhighlight>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang=AutoHotkey"autohotkey">LeftW := "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
RghtW := "PTLNBQDEOYSFAVZKGJRIHWXUMC"
 
Line 512 ⟶ 507:
Cipher text: OAHQHCNYNXTSZJRRHJBYHQKSOUJY
Decipher text: WELLDONEISBETTERTHANWELLSAID</pre>
=={{header|BASIC}}==
{{Works with|FreeBasic}}
{{Works with|PowerBasic}}
<SyntaxHighlight lang="BASIC">
' Caocipher Example
' Rosetta Code
' This code was made in Power Basic 3.5 for DOS
 
CLS
 
' Left Alphabet
Function AlphaLeft(ct as String, pt as String, CharPos as Integer) as String
 
Dim tStr as String: tStr=ct
 
' 1. Shift the entire left alphabet cyclically so the ciphertext letter
' just enciphered is positioned at the zenith (i.e., position 1).
tStr=Right$(ct, Len(ct)-CharPos+1)+Left$(ct, CharPos-1)
 
' 2. Extract the letter found at position zenith+1 (i.e., the letter to
' the right of the zenith), taking it out of the alphabet, temporarily
' leaving an unfilled "hole"
 
Dim Hole as String: Hole=Mid$(tStr, 2, 1): Mid$(tStr, 2, 1)=" "
 
' 3. Shift all letters in positions zenith+2 up to, and including, the
' nadir (zenith+13), moving them one position to the left
 
tStr=Left$(tStr, 1)+Mid$(tStr, 3, 12)+" "+Right$(tStr, 12)
 
' 4. Insert the just-extracted letter into the nadir position
' (i.e., zenith+13)
 
Mid$(tStr, 14, 1)=Hole
 
AlphaLeft=tStr
End Function
 
' Right Alphabet
Function AlphaRight(ct as String, pt as String, CharPos as Integer) as String
 
Dim tStr as String: tStr=pt
 
' 1. Shift the entire right alphabet cyclically so the plaintext letter
' just enciphered is positioned at the zenith.
 
tStr=Right$(tStr, Len(tStr)-CharPos+1)+Left$(tStr, CharPos-1)
 
' 2. Now shift the entire alphabet one more position to the left (i.e.,
' the leftmost letter moves cyclically to the far right), moving a new
' letter into the zenith position.
 
tStr=Right$(tStr, 25)+Left$(tStr, 1)
 
' 3. Extract the letter at position zenith+2, taking it out of the
' alphabet, temporarily leaving an unfilled "hole".
 
Dim Hole as String: Hole=Mid$(tStr, 3, 1): Mid$(tStr, 3, 1)=" ":
 
' 4. Shift all letters beginning with zenith+3 up to, and including, the
' nadir (zenith+13), moving them one position to the left.
 
tStr=Left$(tStr, 2)+Mid$(tStr, 4, 11)+" "+Right$(tStr, 12)
 
' 5. Insert the just-extracted letter into the nadir position (zenith+13)
 
Mid$(tStr, 14, 1)=Hole
 
AlphaRight=tStr
End Function
 
Function Encode(Text as String, ct as String, pt as String) as String
Dim t as Integer
Dim tStr as String: tStr=""
 
For t=1 to Len(Text)
Dim Char as String: Char=Mid$(Text, t, 1)
Dim CharPos as Integer: CharPos=Instr(pt, Char)
 
ct=AlphaLeft(ct, pt, CharPos)
pt=AlphaRight(ct, pt, CharPos)
 
tStr=tStr+Left$(ct, 1)
Next
 
Encode=tStr
End Function
 
' Deciphering a Chaocipher-encrypted message is identical to the steps used
' for enciphering. The sole difference is that the decipherer locates the
' known ciphertext letter in the left (ct) alphabet, with the plaintext
' letter being the corresponding letter in the right (pt) alphabet
'
' Alphabet permuting is identical in enciphering and deciphering
 
Function Decode(Text as String, ct as String, pt as String) as String
Dim t as Integer
Dim tStr as String: tStr=""
 
For t=1 to Len(Text)
Dim Char as String: Char=Mid$(Text, t, 1)
Dim CharPos as Integer: CharPos=Instr(ct, Char)
 
ct=AlphaLeft(ct, pt, CharPos)
pt=AlphaRight(ct, pt, CharPos)
 
tStr=tStr+Right$(pt, 1)
Next
 
Decode=tStr
End Function
 
' Start of Main Code
 
' LEFT (Cipher Text): HXUCZVAMDSLKPEFJRIGTWOBNYQ
Dim tLeft as String: tLeft="HXUCZVAMDSLKPEFJRIGTWOBNYQ"
 
' RIGHT (Plain Text): PTLNBQDEOYSFAVZKGJRIHWXUMC
Dim tRight as String: tRight="PTLNBQDEOYSFAVZKGJRIHWXUMC"
 
' Cipher Message (Used to verify a good encoding)
Dim cText as String: cText="OAHQHCNYNXTSZJRRHJBYHQKSOUJY"
 
' Plain Text Message
Dim pText as String: pText="WELLDONEISBETTERTHANWELLSAID"
Print " Plain Text: "; pText: Print
 
Dim ctLeft as String: ctLeft=tLeft
Dim ptRight as String: ptRight=tRight
 
' Final Cipher Text
Dim eText as String: eText=Encode(pText, ctLeft, ptRight)
Print " Cipher Text: "; eText: Print
 
If eText=cText then Print "Successful" else Print "Failed"
 
ctLeft=tLeft: ptRight=tRight
Dim dText as String: dText=Decode(eText, ctLeft, ptRight)
Print: Print " Plain Text: "; dText: Print
 
If dText=pText then Print "Successful" else Print "Failed"
</SyntaxHighlight>
<pre>
Plain Text: WELLDONEISBETTERTHANWELLSAID
Cipher text: OAHQHCNYNXTSZJRRHJBYHQKSOUJY
Successful
Plain Text: WELLDONEISBETTERTHANWELLSAID
Successful
</pre>
 
=={{header|C}}==
{{trans|Kotlin}}
<syntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Line 627 ⟶ 771:
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|C sharp|C#}}==
{{trans|D}}
<syntaxhighlight lang="csharp">using System;
 
namespace Chaocipher {
Line 733 ⟶ 876:
 
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|C++}}==
{{trans|C#}}
<syntaxhighlight lang="cpp">#include <iostream>
 
enum class Mode {
Line 839 ⟶ 981:
 
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|D}}==
{{trans|Kotlin}}
<syntaxhighlight lang="d">import std.stdio;
import std.string;
 
Line 946 ⟶ 1,087:
{{libheader| System.SysUtils}}
{{Trans|Kotlin}}
<syntaxhighlight lang=Delphi"delphi">
program Chaocipher;
 
Line 1,045 ⟶ 1,186:
readln;
end.</syntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight>
proc index c$ . a$[] ind .
for ind = 1 to len a$[]
if a$[ind] = c$
return
.
.
ind = 0
.
left$ = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
right$ = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
#
func$ chao txt$ mode .
left$[] = strchars left$
right$[] = strchars right$
len tmp$[] 26
for c$ in strchars txt$
# print strjoin left$[] & " " & strjoin right$[]
if mode = 1
index c$ right$[] ind
if ind = 0
return ""
.
r$ &= left$[ind]
else
index c$ left$[] ind
if ind = 0
print c$
return ""
.
r$ &= right$[ind]
.
# permute left
for j = ind to 26
tmp$[j - ind + 1] = left$[j]
.
for j = 1 to ind - 1
tmp$[26 - ind + j + 1] = left$[j]
.
h$ = tmp$[2]
for j = 3 to 14
tmp$[j - 1] = tmp$[j]
.
tmp$[14] = h$
swap tmp$[] left$[]
#
# permute right
for j = ind to 26
tmp$[j - ind + 1] = right$[j]
.
for j = 1 to ind - 1
tmp$[26 - ind + j + 1] = right$[j]
.
h$ = tmp$[1]
for j = 2 to 26
tmp$[j - 1] = tmp$[j]
.
tmp$[26] = h$
h$ = tmp$[3]
for j = 4 to 14
tmp$[j - 1] = tmp$[j]
.
tmp$[14] = h$
swap tmp$[] right$[]
.
return r$
.
h$ = chao "WELLDONEISBETTERTHANWELLSAID" 1
print h$
print chao h$ 2
</syntaxhighlight>
{{out}}
<pre>
OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|EMal}}==
{{trans|C#}}
<syntaxhighlight lang="emal">
type Chaocipher:Mode
enum
int ENCRYPT, DECRYPT
end
type Chaocipher
text L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
text R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
fun exec = text by text value, Chaocipher:Mode mode, logic showSteps
^|since texts are mutable, we can operate directly on them without the need of Lists|^
text left = *L_ALPHABET # by using the valueOf operator we are sure that the string is copied
text right = *R_ALPHABET
text eText = text(" ", value.length)
text temp = text(" ", 26)
for int i = 0; i < value.length; ++i
if showSteps do writeLine(left + " " + right) end
int index = 0
if mode == Chaocipher:Mode.ENCRYPT
index = right.find(value[i])
eText[i] = left[index]
else
index = left.find(value[i])
eText[i] = right[index]
end
if i == value.length - 1 do break end
# permute left
for int j = index; j < 26; ++j do temp[j - index] = left[j] end
for int j = 0; j < index; ++j do temp[26 - index + j] = left[j] end
var store = temp[1]
for int j = 2; j < 14; ++j do temp[j - 1] = temp[j] end
temp[13] = store
left = *temp
# permute right
for int j = index; j < 26; ++j do temp[j - index] = right[j] end
for int j = 0; j < index; ++j do temp[26 - index + j] = right[j] end
store = temp[0]
for int j = 1; j < 26; ++j do temp[j - 1] = temp[j] end
temp[25] = store
store = temp[2]
for int j = 3; j < 14; ++j do temp[j - 1] = temp[j] end
temp[13] = store
right = *temp
end
return eText
end
var plainText = "WELLDONEISBETTERTHANWELLSAID"
writeLine("The original plaintext is : " + plainText)
writeLine(EOL + "The left and right alphabets after each permutation during encryption are :" + EOL)
var cipherText = exec(plainText, Chaocipher:Mode.ENCRYPT, true)
writeLine(EOL + "The ciphertext is : " + cipherText)
var plainText2 = exec(cipherText, Chaocipher:Mode.DECRYPT, false)
writeLine(EOL + "The recovered plaintext is : " + plainText2)
</syntaxhighlight>
{{out}}
<pre>
The original plaintext is : WELLDONEISBETTERTHANWELLSAID
 
The left and right alphabets after each permutation during encryption are :
 
HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ADBSLKPEFJRIGMTWONYQHXUCZV OYSFAVZKGJRIHMWXUCPTLNBQDE
HUCZVADBSLKPEXFJRIGMTWONYQ NBDEOYSFAVZKGQJRIHMWXUCPTL
QUCZVADBSLKPEHXFJRIGMTWONY NBEOYSFAVZKGQDJRIHMWXUCPTL
HFJRIGMTWONYQXUCZVADBSLKPE JRHMWXUCPTLNBIEOYSFAVZKGQD
CVADBSLKPEHFJZRIGMTWONYQXU YSAVZKGQDJRHMFWXUCPTLNBIEO
NQXUCVADBSLKPYEHFJZRIGMTWO BIOYSAVZKGQDJERHMFWXUCPTLN
YHFJZRIGMTWONEQXUCVADBSLKP RHFWXUCPTLNBIMOYSAVZKGQDJE
NQXUCVADBSLKPEYHFJZRIGMTWO MOSAVZKGQDJERYHFWXUCPTLNBI
XCVADBSLKPEYHUFJZRIGMTWONQ AVKGQDJERYHFWZXUCPTLNBIMOS
TONQXCVADBSLKWPEYHUFJZRIGM IMSAVKGQDJERYOHFWZXUCPTLNB
SKWPEYHUFJZRILGMTONQXCVADB RYHFWZXUCPTLNOBIMSAVKGQDJE
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
</pre>
 
=={{header|F_Sharp|F#}}==
===The Functions===
<syntaxhighlight lang="fsharp">
// Implement Chaocipher. Nigel Galloway: July 13th., 2019
let 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+1
Line 1,059 ⟶ 1,373:
 
===The Task===
<syntaxhighlight lang="fsharp">
printfn "%s" (encrypt ("HXUCZVAMDSLKPEFJRIGTWOBNYQ".ToCharArray()) ("PTLNBQDEOYSFAVZKGJRIHWXUMC".ToCharArray()) ("WELLDONEISBETTERTHANWELLSAID".ToCharArray()))
printfn "%s" (decrypt ("HXUCZVAMDSLKPEFJRIGTWOBNYQ".ToCharArray()) ("PTLNBQDEOYSFAVZKGJRIHWXUMC".ToCharArray()) ("OAHQHCNYNXTSZJRRHJBYHQKSOUJY".ToCharArray()))
Line 1,068 ⟶ 1,382:
WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: arrays combinators fry io kernel locals math namespaces
prettyprint sequences sequences.extras strings ;
IN: rosetta-code.chaocipher
Line 1,136 ⟶ 1,449:
WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Chaocipher}}
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 &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''Solution'''
Programs in Fōrmulæ are created/edited online in its [https://formulae.org 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.
 
[[File:Fōrmulæ - Chaocipher 01.png]]
 
'''Test 1.''' Encryption
 
[[File:Fōrmulæ - Chaocipher 02.png]]
 
[[File:Fōrmulæ - Chaocipher 03.png]]
 
'''Test 2.''' Decryption
 
[[File:Fōrmulæ - Chaocipher 04.png]]
 
[[File:Fōrmulæ - Chaocipher 05.png]]
 
=={{header|FreeBASIC}}==
The [[#BASIC|BASIC]] solution works without any changes.
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="FutureBasic">
 
begin enum
_encrypt
_decrypt
end enum
 
local fn chaocipher(orig as str255, action as byte, show as bool) as str255
str255 leftStr, rightStr, out
short i, index
leftStr = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
rightStr = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
orig = ucase$(orig)
out[0] = orig[0]
if show then print:print,"The left and right alphabets during encryption are:":print
for i = 1 to orig[0]
if show then print ,leftStr,,rightStr
if action == _encrypt
index = instr$(0, rightStr, mid$(orig, i, 1))
out[i] = leftStr[index]
else
index = instr$(0, leftStr, mid$(orig, i, 1))
out[i] = rightStr[index]
end if
//leftStr permutation
leftStr = mid$(leftStr, index) + left$(leftStr, index-1)
leftStr = left$(leftStr, 1) + mid$(leftStr, 3, 12) + mid$(leftStr, 2, 1) + mid$(leftStr, 15)
//rightStr permutation
rightStr = mid$(rightStr, index+1) + left$(rightStr, index-1) + mid$(rightStr, index, 1)
rightStr = left$(rightStr, 2) + mid$(rightStr, 4, 11) + mid$(rightStr, 3, 1) + mid$(rightStr, 15)
next
end fn = out
 
 
str255 original, encrypted, decrypted
original = "WellDoneIsBetterThanWellSaid"
 
window 1, @"Chaocipher", ( 0, 0, 475, 550 )
print : print ,"The original text is: """; original; """"
encrypted = fn chaocipher(original, _encrypt, yes)
print : print ,"The encrypted text is: """; encrypted; """"
decrypted = fn chaocipher(encrypted, _decrypt, no)
print : print ,"The decrypted text is: """; decrypted; """"
handleevents
 
</syntaxhighlight>
{{out}}
[[File:FB Chaocipher results.png]]
 
In '''[https://formulae.org/?example=Chaocipher this]''' page you can see the program(s) related to this task and their results.
 
=={{header|Go}}==
{{trans|Kotlin}}
<syntaxhighlight lang="go">package main
 
import(
Line 1,250 ⟶ 1,633:
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class Chaocipher {
private enum Mode {
ENCRYPT,
Line 1,365 ⟶ 1,748:
 
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.List (elemIndex)
 
chao :: Eq a => [a] -> [a] -> Bool -> [a] -> [a]
Line 1,417 ⟶ 1,799:
"WELLDONEISBETTERTHANWELLSAID"</pre>
 
=={{header|J}}==
{{trans|Raku}}
<syntaxhighlight lang="j">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</syntaxhighlight>
 
{{out}}
<pre>
OMUUADCMTLZMXXMGXWPCOMUULPTA
WELLDONEISBETTERTHANWELLSAID
</pre>
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">import java.util.Arrays;
 
public class Chaocipher {
Line 1,536 ⟶ 1,957:
 
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|J}}==
{{trans|Raku}}
<syntaxhighlight lang=j>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</syntaxhighlight>
 
{{out}}
<pre>
OMUUADCMTLZMXXMGXWPCOMUULPTA
WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|JavaScript}}==
{{trans|C}}
Script source
<syntaxhighlight lang="javascript">const L_ALPHABET = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
const R_ALPHABET = "PTLNBQDEOYSFAVZKGJRIHWXUMC";
 
Line 1,682 ⟶ 2,062:
 
Solution page
<syntaxhighlight lang="html"><!DOCTYPE html>
<html>
<head>
Line 1,696 ⟶ 2,076:
The ciphertext is : OAHQHCNYNXTSZJRRHJBYHQKSOUJY
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|Julia}}==
Modified from the Kotlin and Raku entries.
<syntaxhighlight lang="julia">const leftalphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
const rightalphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
 
Line 1,767 ⟶ 2,146:
Decoded, the recovered plaintext is: WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|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.
<syntaxhighlight lang="scala">// Version 1.2.40
 
enum class Mode { ENCRYPT, DECRYPT }
Line 1,873 ⟶ 2,251:
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
</pre>
 
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">-- Chaocipher, in Lua, 6/19/2020 db
local Chaocipher = {
ct = "HXUCZVAMDSLKPEFJRIGTWOBNYQ",
Line 1,935 ⟶ 2,311:
The encrypted text is: OAHQHCNYNXTSZJRRHJBYHQKSOUJY
The decrypted text is: WELLDONEISBETTERTHANWELLSAID</pre>
 
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">ClearAll[ichaoalphabet, iMoveToFront, ChaoCipher]
ichaoalphabet = CharacterRange["A", "Z"];
iMoveToFront[l_List, sel_] := Module[{p},
Line 1,986 ⟶ 2,360:
{{out}}
<pre>OAHQHCNYNXTSZJRRHJBYHQKSOUJY</pre>
 
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import strformat
 
type
Line 2,099 ⟶ 2,472:
===Another implementation===
Using functions from the stdlib instead of manual array manipulations:
<syntaxhighlight lang="nim">import std/[algorithm, strutils]
 
type
Line 2,147 ⟶ 2,520:
echo "\nThe recovered plaintext is: ", plainText2</syntaxhighlight>
Same output as above.
 
=={{header|Objeck}}==
{{trans|Kotlin}}
<syntaxhighlight lang="objeck">class Chaocipher {
L_ALPHABET : static : Char[];
R_ALPHABET : static : Char[];
Line 2,268 ⟶ 2,640:
The recovered plaintext is: WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|Pascal}}==
{{works with|Extended Pascal}}
<syntaxhighlight lang="pascal">program chaocipher(input, output);
 
const
Line 2,499 ⟶ 2,870:
{{trans|Raku}}
Since <tt>rotate</tt> is not a built-in in Perl, using a custom one, not general-purpose but sufficient for this task.
<syntaxhighlight lang="perl>sub" initline>use {strict;
use warnings;
my(@left,@right,$e_msg,$d_msg);
 
sub init {
@left = split '', 'HXUCZVAMDSLKPEFJRIGTWOBNYQ';
@right = split '', 'PTLNBQDEOYSFAVZKGJRIHWXUMC';
Line 2,535 ⟶ 2,910:
 
sub rotate {
ourmy @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$d_msg\n";</syntaxhighlight>
print "$d_msg\n";</syntaxhighlight>
{{out}}
<pre>OMUUADCMTLZMXXMGXWPCOMUULPTA
<pre>OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|Phix}}==
Originally translated from C, but ended up more of a direct implementation of the algorithm in the pdf.
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Chao_cipher.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 2,603 ⟶ 2,977:
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|Python}}==
===Procedural===
<syntaxhighlight lang="python"># Python3 implementation of Chaocipher
# left wheel = ciphertext wheel
# right wheel = plaintext wheel
Line 2,727 ⟶ 3,100:
{{Trans|Haskell}}
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Chaocipher'''
 
from itertools import chain, cycle, islice
Line 2,917 ⟶ 3,290:
OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|QBasic}}==
{{trans|BASIC}}
<syntaxhighlight lang="qbasic">DECLARE FUNCTION AlphaLeft$ (ct$, pt$, CharPos!)
DECLARE FUNCTION AlphaRight$ (ct$, pt$, CharPos!)
DECLARE FUNCTION Decode$ (Text$, ct$, pt$)
DECLARE FUNCTION Encode$ (Text$, ct$, pt$)
 
CLS
 
' Deciphering a Chaocipher-encrypted message is identical to the steps used
' for enciphering. The sole difference is that the decipherer locates the
' known ciphertext letter in the left (ct$) alphabet, with the plaintext
' letter being the corresponding letter in the right (pt$) alphabet
'
' Alphabet permuting is identical in enciphering and deciphering
 
' Start of Main Code
 
' LEFT (Cipher Text$): HXUCZVAMDSLKPEFJRIGTWOBNYQ
tLeft$ = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
 
' RIGHT (Plain Text$): PTLNBQDEOYSFAVZKGJRIHWXUMC
tRight$ = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
 
' Cipher Message (Used to verify a good encoding)
cText$ = "OAHQHCNYNXTSZJRRHJBYHQKSOUJY"
 
' Plain Text$ Message
pText$ = "WELLDONEISBETTERTHANWELLSAID"
PRINT " Plain Text$: "; pText$
PRINT
 
ctLeft$ = tLeft$
ptRight$ = tRight$
 
' Final Cipher Text$
eText$ = Encode$(pText$, ctLeft$, ptRight$)
PRINT " Cipher Text$: "; eText$
PRINT
 
IF eText$ = cText$ THEN PRINT "Successful" ELSE PRINT "Failed"
 
ctLeft$ = tLeft$
ptRight$ = tRight$
dText$ = Decode$(eText$, ctLeft$, ptRight$)
PRINT
PRINT " Plain Text$: "; dText$
PRINT
 
IF dText$ = pText$ THEN PRINT "Successful" ELSE PRINT "Failed"
END
 
' Left Alphabet
FUNCTION AlphaLeft$ (ct$, pt$, CharPos)
tStr$ = ct$
' 1. Shift the entire left alphabet cyclically so the ciphertext letter
' just enciphered is positioned at the zenith (i.e., position 1).
tStr$ = RIGHT$(ct$, LEN(ct$) - CharPos + 1) + LEFT$(ct$, CharPos - 1)
' 2. Extract the letter found at position zenith+1 (i.e., the letter to
' the right of the zenith), taking it out of the alphabet, temporarily
' leaving an unfilled "Hole$"
Hole$ = MID$(tStr$, 2, 1)
MID$(tStr$, 2, 1) = " "
' 3. Shift all letters in positions zenith+2 up to, and including, the
' nadir (zenith+13), moving them one position to the left
tStr$ = LEFT$(tStr$, 1) + MID$(tStr$, 3, 12) + " " + RIGHT$(tStr$, 12)
' 4. Insert the just-extracted letter into the nadir position
' (i.e., zenith+13)
MID$(tStr$, 14, 1) = Hole$
AlphaLeft$ = tStr$
END FUNCTION
 
' Right Alphabet
FUNCTION AlphaRight$ (ct$, pt$, CharPos)
tStr$ = pt$
' 1. Shift the entire right alphabet cyclically so the plaintext letter
' just enciphered is positioned at the zenith.
tStr$ = RIGHT$(tStr$, LEN(tStr$) - CharPos + 1) + LEFT$(tStr$, CharPos - 1)
' 2. Now shift the entire alphabet one more position to the left (i.e.,
' the leftmost letter moves cyclically to the far right), moving a new
' letter into the zenith position.
tStr$ = RIGHT$(tStr$, 25) + LEFT$(tStr$, 1)
' 3. Extract the letter at position zenith+2, taking it out of the
' alphabet, temporarily leaving an unfilled "Hole$".
Hole$ = MID$(tStr$, 3, 1)
MID$(tStr$, 3, 1) = " ":
' 4. Shift all letters beginning with zenith+3 up to, and including, the
' nadir (zenith+13), moving them one position to the left.
tStr$ = LEFT$(tStr$, 2) + MID$(tStr$, 4, 11) + " " + RIGHT$(tStr$, 12)
' 5. Insert the just-extracted letter into the nadir position (zenith+13)
MID$(tStr$, 14, 1) = Hole$
AlphaRight$ = tStr$
END FUNCTION
 
FUNCTION Decode$ (Text$, ct$, pt$)
tStr$ = ""
FOR t = 1 TO LEN(Text$)
Char$ = MID$(Text$, t, 1)
CharPos = INSTR(ct$, Char$)
ct$ = AlphaLeft$(ct$, pt$, CharPos)
pt$ = AlphaRight$(ct$, pt$, CharPos)
tStr$ = tStr$ + RIGHT$(pt$, 1)
NEXT
Decode$ = tStr$
END FUNCTION
 
FUNCTION Encode$ (Text$, ct$, pt$)
tStr$ = ""
FOR t = 1 TO LEN(Text$)
Char$ = MID$(Text$, t, 1)
CharPos = INSTR(pt$, Char$)
ct$ = AlphaLeft$(ct$, pt$, CharPos)
pt$ = AlphaRight$(ct$, pt$, CharPos)
tStr$ = tStr$ + LEFT$(ct$, 1)
NEXT
Encode$ = tStr$
END FUNCTION
</syntaxhighlight>
 
=={{header|Raku}}==
Line 2,922 ⟶ 3,441:
{{works with|Rakudo|2018.03}}
 
<syntaxhighlight lang="raku" line>my @left;
my @right;
 
Line 2,958 ⟶ 3,477:
<pre>OAHQHCNYNXTSZJRRHJBYHQKSOUJY
WELLDONEISBETTERTHANWELLSAID</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">txt = "WELLDONEISBETTERTHANWELLSAID"
@left = "HXUCZVAMDSLKPEFJRIGTWOBNYQ".chars
@right = "PTLNBQDEOYSFAVZKGJRIHWXUMC".chars
Line 2,983 ⟶ 3,501:
<pre>OAHQHCNYNXTSZJRRHJBYHQKSOUJY
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">const LEFT_ALPHABET_CT: &str = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
const RIGHT_ALPHABET_PT: &str = "PTLNBQDEOYSFAVZKGJRIHWXUMC";
const ZENITH: usize = 0;
Line 3,020 ⟶ 3,537:
<pre>Plaintext: WELLDONEISBETTERTHANWELLSAID
Ciphertext: OAHQHCNYNXTSZJRRHJBYHQKSOUJY</pre>
 
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
templates chaocipher&{left:,right:,decode:}
templates permute
Line 3,060 ⟶ 3,576:
WELLDONEISBETTERTHANWELLSAID
</pre>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
 
ReadOnly L_ALPHABET As String = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
Line 3,178 ⟶ 3,693:
 
The recovered plaintext is : WELLDONEISBETTERTHANWELLSAID</pre>
=={{header|V (Vlang)}}==
 
=={{header|Vlang}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">type Mode = int
const(
encrypt = Mode(0)
Line 3,273 ⟶ 3,787:
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang=ecmascript"wren">class Chao {
static encrypt { 0 }
static decrypt { 1 }
Line 3,328 ⟶ 3,842:
System.print("\nThe recovered plaintext is : %(plainText2)")</syntaxhighlight>
 
{{out}}
<pre>
The original plaintext is : WELLDONEISBETTERTHANWELLSAID
 
The left and right alphabets after each permutation during encryption are :
 
HXUCZVAMDSLKPEFJRIGTWOBNYQ PTLNBQDEOYSFAVZKGJRIHWXUMC
ONYQHXUCZVAMDBSLKPEFJRIGTW XUCPTLNBQDEOYMSFAVZKGJRIHW
ADBSLKPEFJRIGMTWONYQHXUCZV OYSFAVZKGJRIHMWXUCPTLNBQDE
HUCZVADBSLKPEXFJRIGMTWONYQ NBDEOYSFAVZKGQJRIHMWXUCPTL
QUCZVADBSLKPEHXFJRIGMTWONY NBEOYSFAVZKGQDJRIHMWXUCPTL
HFJRIGMTWONYQXUCZVADBSLKPE JRHMWXUCPTLNBIEOYSFAVZKGQD
CVADBSLKPEHFJZRIGMTWONYQXU YSAVZKGQDJRHMFWXUCPTLNBIEO
NQXUCVADBSLKPYEHFJZRIGMTWO BIOYSAVZKGQDJERHMFWXUCPTLN
YHFJZRIGMTWONEQXUCVADBSLKP RHFWXUCPTLNBIMOYSAVZKGQDJE
NQXUCVADBSLKPEYHFJZRIGMTWO MOSAVZKGQDJERYHFWXUCPTLNBI
XCVADBSLKPEYHUFJZRIGMTWONQ AVKGQDJERYHFWZXUCPTLNBIMOS
TONQXCVADBSLKWPEYHUFJZRIGM IMSAVKGQDJERYOHFWZXUCPTLNB
SKWPEYHUFJZRILGMTONQXCVADB RYHFWZXUCPTLNOBIMSAVKGQDJE
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
</pre>
 
=={{header|XPL0}}==
{{trans|C}}
<syntaxhighlight lang "XPL0">include xpllib; \For StrLen, StrCopy, Print
 
func StrChar(Str, C);
char Str, C;
[loop [if Str(0) = 0 then return 0;
if Str(0) = C then return Str;
Str:= Str+1;
];
];
 
def \CMode\ ENCRYPT, DECRYPT;
char L_alphabet, R_alphabet;
 
proc Chao(In, Out, Mode, Show_steps);
char In, Out, Mode, Show_steps;
int Len, I, J, Index;
char Store, Left(27), Right(27), Temp(27);
[Len:= StrLen(In);
StrCopy(Left, L_alphabet);
StrCopy(Right, R_alphabet);
Temp(26):= 0;
 
for I:= 0 to Len-1 do
[if Show_steps then Print("%s %s\n", Left, Right);
if Mode = ENCRYPT then
[Index:= StrChar(Right, In(I)) - Right;
Out(I):= Left(Index);
]
else [Index:= StrChar(Left, In(I)) - Left;
Out(I):= Right(Index);
];
if I = Len-1 then return;
 
\Permute Left
for J:= Index to 26-1 do Temp(J-Index):= Left(J);
for J:= 0 to Index-1 do Temp(26-Index+J):= Left(J);
Store:= Temp(1);
for J:= 2 to 14-1 do Temp(J-1):= Temp(J);
Temp(13):= Store;
StrCopy(Left, Temp);
 
\Permute Right
for J:= Index to 26-1 do Temp(J-Index):= Right(J);
for J:= 0 to Index-1 do Temp(26-Index+J):= Right(J);
Store:= Temp(0);
for J:= 1 to 26-1 do Temp(J-1):= Temp(J);
Temp(25):= Store;
Store:= Temp(2);
for J:= 3 to 14-1 do Temp(J-1):= Temp(J);
Temp(13):= Store;
StrCopy(Right, Temp);
];
];
 
char Plain_text, Cipher_text, Plain_text2;
[L_alphabet:= "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
R_alphabet:= "PTLNBQDEOYSFAVZKGJRIHWXUMC";
Plain_text:= "WELLDONEISBETTERTHANWELLSAID";
Cipher_text:= MAlloc(StrLen(Plain_text) + 1);
Plain_text2:= MAlloc(StrLen(Plain_text) + 1);
Print("The original plaintext is : %s\n", Plain_text);
Print("\nThe left and right alphabets after each permutation during encryption are :\n\n");
Chao(Plain_text, Cipher_text, ENCRYPT, true);
Print("\nThe ciphertext is : %s\n", Cipher_text);
Chao(Cipher_text, Plain_text2, DECRYPT, false);
Print("\nThe recovered plaintext is : %s\n", Plain_text2);
Release(Cipher_text);
Release(Plain_text2);
]</syntaxhighlight>
{{out}}
<pre>
Line 3,370 ⟶ 3,995:
=={{header|zkl}}==
{{trans|Raku}}
<syntaxhighlight lang="zkl">class Chao{
var [const private] lAlphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ",
rAlphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC";
Line 3,398 ⟶ 4,023:
}
}</syntaxhighlight>
<syntaxhighlight lang="zkl">plainText:="WELLDONEISBETTERTHANWELLSAID";
println("The original plaintext is : ",plainText);
println("\nThe left and right alphabets after each permutation"
1,983

edits