Straddling checkerboard: Difference between revisions

Added FreeBASIC
m (no longer draft)
(Added FreeBASIC)
 
(42 intermediate revisions by 15 users not shown)
Line 1:
{{task|Encryption}}
 
;Task:
Implement functions to encrypt and decrypt a message using the [[wp:Straddling_checkerboard|straddling checkerboard]] method. The checkerboard should take a 28 character alphabet (A-Z plus a full stop and an escape character) and two different numbers representing the blanks in the first row. The output will be a series of decimal digits.
 
Numbers should be encrypted by inserting the escape character before each digit, then including the digit unencrypted. This should be reversed for decryption.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V t = [[String(‘79’), ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’],
[String(‘’), ‘H’, ‘O’, ‘L’, ‘’, ‘M’, ‘E’, ‘S’, ‘’, ‘R’, ‘T’],
[String(‘3’), ‘A’, ‘B’, ‘C’, ‘D’, ‘F’, ‘G’, ‘I’, ‘J’, ‘K’, ‘N’],
[String(‘7’), ‘P’, ‘Q’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘.’, ‘/’]]
 
F straddle(s)
R multiloop_filtered(Array(s.uppercase()), :t, (c, l) -> c C l, (c, l) -> l[0]‘’:t[0][l.index(c)]).join(‘’)
 
F unstraddle(s)
[String] r
V si = 0
F next()
R @s[@si++]
L
I si == s.len
L.break
V c = s[si++]
I c C (:t[2][0], :t[3][0])
V i = [:t[2][0], :t[3][0]].index(c)
V n = :t[2 + i][:t[0].index(next())]
r [+]= I n == ‘/’ {next()} E n
E
r [+]= :t[1][:t[0].index(c)]
R r
 
V O = ‘One night-it was on the twentieth of March, 1888-I was returning’
print(‘Encoded: ’straddle(O))
print(‘Decoded: ’unstraddle(straddle(O)).join(‘’))</syntaxhighlight>
 
{{out}}
<pre>
Encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
Decoded: ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</pre>
 
=={{header|ALGOL 68}}==
Line 10 ⟶ 50:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
<langsyntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
 
PRIO MIN=5, MAX=5;
Line 127 ⟶ 167:
))
 
)</langsyntaxhighlight>
Output:
<pre>
Line 136 ⟶ 176:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">board := "
(
ET AON RIS
Line 176 ⟶ 216:
}
}
MsgBox % dec</langsyntaxhighlight>
 
=={{header|C}}==
{{libheader|GLib}}
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 392 ⟶ 433:
 
return 0;
}</langsyntaxhighlight>
 
===Shorter version===
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 482 ⟶ 523:
decipher(enc, dec, 1); printf("decoded: %s\n", dec);
return 0;
}</langsyntaxhighlight>Output:<syntaxhighlight lang="text">message: In the winter 1965/we were hungry/just barely alive
encoded: 85621250626585107626916996966956265062650706225635247676226639162203702867623288640
decoded: IN THE WINTER 1965 WE WERE HUNGRY JUST BARELY ALIVE
Line 488 ⟶ 529:
No spaces:
encoded: 851250658510769169969669562650650702563524767622663912037028673288640
decoded: INTHEWINTER1965/WEWEREHUNGRY/JUSTBARELYALIVE</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
Translation of [[Straddling_checkerboard#Java|Java]] via [[Straddling_checkerboard#D|D]]
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
 
namespace StraddlingCheckerboard
{
class Program
{
public readonly static IReadOnlyDictionary<char, string> val2Key;
public readonly static IReadOnlyDictionary<string, char> key2Val;
 
static Program()
{
val2Key = new Dictionary<char, string> {
{'A',"30"}, {'B',"31"}, {'C',"32"}, {'D',"33"}, {'E',"5"}, {'F',"34"}, {'G',"35"},
{'H',"0"}, {'I',"36"}, {'J',"37"}, {'K',"38"}, {'L',"2"}, {'M',"4"}, {'.',"78"},
{'N',"39"}, {'/',"79"}, {'O',"1"}, {'0',"790"}, {'P',"70"}, {'1',"791"}, {'Q',"71"},
{'2',"792"}, {'R',"8"}, {'3',"793"}, {'S',"6"}, {'4',"794"}, {'T',"9"}, {'5',"795"},
{'U',"72"}, {'6',"796"},{'V',"73"}, {'7',"797"}, {'W',"74"}, {'8',"798"}, {'X',"75"},
{'9',"799"}, {'Y',"76"}, {'Z',"77"}};
 
key2Val = val2Key.ToDictionary(kv => kv.Value, kv => kv.Key);
}
 
public static string Encode(string s)
{
return string.Concat(s.ToUpper().ToCharArray()
.Where(c => val2Key.ContainsKey(c)).Select(c => val2Key[c]));
}
 
public static string Decode(string s)
{
return string.Concat(Regex.Matches(s, "79.|7.|3.|.").Cast<Match>()
.Where(m => key2Val.ContainsKey(m.Value)).Select(m => key2Val[m.Value]));
}
 
static void Main(string[] args)
{
var enc = Encode("One night-it was on the twentieth of March, 1888-I was returning");
Console.WriteLine(enc);
Console.WriteLine(Decode(enc));
 
Console.ReadLine();
}
}
}</syntaxhighlight>
<pre>139539363509369743061399059745399365901344308320791798798798367430685972839363935
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <map>
Line 580 ⟶ 673:
return out;
}
};</langsyntaxhighlight>
 
Test program:
<langsyntaxhighlight lang="cpp">int main()
{
StraddlingCheckerboard sc("HOLMESRTABCDFGIJKNPQUVWXYZ./", 3, 7);
Line 596 ⟶ 689:
 
return 0;
}</langsyntaxhighlight>
 
Output:
Line 607 ⟶ 700:
=={{header|D}}==
Partially based on the PicoLisp version:
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.string, std.array;
 
immutable T = ["79|0|1|2|3|4|5|6|7|8|9", "|H|O|L||M|E|S||R|T",
Line 642 ⟶ 735:
writeln("Encoded: ", O.straddle);
writeln("Decoded: ", O.straddle.unStraddle);
}</langsyntaxhighlight>
{{out}}
<pre>Encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
Line 650 ⟶ 743:
{{trans|C++}}
Same output:
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.ascii;
 
struct StraddlingCheckerboard {
Line 724 ⟶ 817:
writeln("Encoded: ", en);
writeln("Decoded: ", sc.decode(en));
}</langsyntaxhighlight>
 
===Dictionary-Based Version===
{{trans|Java}}
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.algorithm, std.regex, std.array, std.range, std.typecons;
 
immutable string[const string] val2key, key2val;
Line 755 ⟶ 848:
s.encode.writeln;
s.encode.decode.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>139539363509369743061399059745399365901344308320791798798798367430685972839363935
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</pre>
 
=={{header|FreeBASIC}}==
{{trans|Go}}
<syntaxhighlight lang="vbnet">Function Encipher(bd As String, pt As String) As String
Dim As String enc(256), row(3), r2d, r3d, d, num, ct
Dim As Integer i = 1, j, col
For j = 0 To 3
row(j) = Mid(bd, i, Instr(i, bd, Chr(10)) - i)
i = Instr(i, bd, Chr(10)) + 1
Next j
r2d = Mid(row(2), 1, 1)
r3d = Mid(row(3), 1, 1)
For col = 1 To 10
d = Mid(row(0), col+1, 1)
enc(Asc(Mid(row(1), col+1, 1))) = d
enc(Asc(Mid(row(2), col+1, 1))) = r2d + d
enc(Asc(Mid(row(3), col+1, 1))) = r3d + d
Next col
num = enc(Asc("/"))
enc(Asc("/")) = ""
enc(Asc(" ")) = ""
ct = ""
For i = 0 To Len(pt)-1
j = Asc(Mid(pt, i+1, 1))
If j <= Asc("9") And j >= Asc("0") Then
ct += num + Chr(j)
Else
If j <= Asc("z") And j >= Asc("a") Then
j -= Asc("a") - Asc("A")
End If
ct += enc(j)
End If
Next i
Return ct
End Function
 
Function Decipher(bd As String, ct As String) As String
Dim As String row(3), pt, b
Dim As Integer i = 1, j, cx(10), r2d, r3d, r, d
For j = 0 To 3
row(j) = Mid(bd, i, Instr(i, bd, Chr(10)) - i)
i = Instr(i, bd, Chr(10)) + 1
Next j
For i = 1 To 10
cx(Asc(Mid(row(0), i+1, 1)) - Asc("0")) = i
Next i
r2d = Asc(Mid(row(2), 1, 1)) - Asc("0")
r3d = Asc(Mid(row(3), 1, 1)) - Asc("0")
pt = ""
i = 0
While i < Len(ct)
d = Asc(Mid(ct, i+1, 1)) - Asc("0")
If d = r2d Then
r = 2
Elseif d = r3d Then
r = 3
Else
pt += Mid(row(1), cx(d)+1, 1)
i += 1
Continue While
End If
i += 1
b = Mid(row(r), cx(Asc(Mid(ct, i+1, 1)) - Asc("0"))+1, 1)
If b = "/" Then
i += 1
pt += Mid(ct, i+1, 1)
Else
pt += b
End If
i += 1
Wend
Return pt
End Function
 
Dim As String key = _
" 8752390146" + Chr(10) + _
" ET AON RIS" + Chr(10) + _
"5BC/FGHJKLM" + Chr(10) + _
"0PQD.VWXYZU"
Dim p As String = "you have put on 7.5 pounds since I saw you."
Print p
Dim c As String = Encipher(key, p)
Print c
Print Decipher(key, c)
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Go entry.</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
(*
Encode and Decode using StraddlingCheckerboard
Nigel Galloway May 15th., 2017
*)
type G={n:char;i:char;g:System.Collections.Generic.Dictionary<(char*char),string>;e:System.Collections.Generic.Dictionary<char,string>}
member G.encode n=n|>Seq.map(fun n->if (n='/') then G.e.['/']+string n else match (G.e.TryGetValue(n)) with |(true,n)->n|(false,_)->G.e.['/']+string n)
member G.decode n =
let rec fn n = seq{ if not (Seq.isEmpty n)
then match (match Seq.head n with |g when g=G.n||g=G.i->(G.g.[(g,(Seq.item 1 n))],(Seq.skip 2 n))|g->(G.g.[('/',g)],(Seq.tail n))) with
|(a,b) when a="/"->yield string (Seq.head b); yield! fn (Seq.tail b)
|(a,b) ->yield a; yield! fn b
}
fn n
let G n i g e l z=
let a = new System.Collections.Generic.Dictionary<(char*char),string>()
let b = new System.Collections.Generic.Dictionary<char,string>()
Seq.iter2 (fun ng gn->a.[('/' ,char ng)]<-string gn;b.[gn]<-ng) (List.except [n;i] z) g
Seq.iter2 (fun ng gn->a.[(char n,char ng)]<-string gn;b.[gn]<-n+ng) z e
Seq.iter2 (fun ng gn->a.[(char i,char ng)]<-string gn;b.[gn]<-i+ng) z l
{n=char n;i=char i;g=a;e=b}
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="fsharp">
let N = G "2" "6" "ETAONRIS" "BCDFGHJKLM" "PQ/UVWXYZ." ["0";"1";"2";"3";"4";"5";"6";"7";"8";"9"]
N.decode "450582425181653945125016505180125423293721256216286286288653970163758524"|>Seq.iter(fun n->printf "%s" n);; //ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
N.encode "IN THE WINTER 1965 WE WERE HUNGRY JUST BARELY ALIVE"|>Seq.iter(fun n->printfn "%s" n);; //8562 125062 658510762 62162962662562 65062 6507062 256352476762 26639162 20370286762 3288640
N.decode "8562 125062 658510762 62162962662562 65062 6507062 256352476762 26639162 20370286762 3288640"|>Seq.iter(fun n->printf "%s" n);; //IN THE WINTER 1965 WE WERE HUNGRY JUST BARELY ALIVE
</syntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 836 ⟶ 1,051:
}
return
}</langsyntaxhighlight>
{{out}}
<pre>
Line 842 ⟶ 1,057:
01306592038080673955702555083069056649578462090130602
YOUHAVEPUTON7.5POUNDSSINCEISAWYOU.
</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.Char
import Data.Map
 
charToInt :: Char -> Int
charToInt c = ord c - ord '0'
 
-- Given a string, decode a single character from the string.
-- Return the decoded char and the remaining undecoded string.
decodeChar :: String -> (Char,String)
decodeChar ('7':'9':r:rs) = (r,rs)
decodeChar ('7':r:rs) = ("PQUVWXYZ. " !! charToInt r, rs)
decodeChar ('3':r:rs) = ("ABCDFGIJKN" !! charToInt r, rs)
decodeChar (r:rs) = ("HOL MES RT" !! charToInt r, rs)
 
-- Decode an entire string.
decode :: String -> String
decode [] = []
decode st = let (c, s) = decodeChar st in c:decode s
 
-- Given a string, decode a single character from the string.
-- Return the decoded char and the part of the encoded string
-- used to encode that character.
revEnc :: String -> (Char, String)
revEnc enc = let (dec, rm) = decodeChar enc in (dec, take (length enc - length rm) enc)
 
ds :: String
ds = ['0'..'9']
 
-- Decode all 1000 possible encodings of three digits and
-- use results to construct map used to encode.
encodeMap :: Map Char String
encodeMap = fromList [ revEnc [d2,d1,d0] | d2 <- ds, d1 <- ds, d0 <- ds ]
 
-- Encode a single char using encoding map.
encodeChar :: Char -> String
encodeChar c = findWithDefault "" c encodeMap
 
-- Encode an entire string.
encode :: String -> String
encode st = concatMap encodeChar $ fmap toUpper st
 
-- Test by encoding, decoding, printing results.
main = let orig = "One night-it was on the twentieth of March, 1888-I was returning"
enc = encode orig
dec = decode enc
in mapM_ putStrLn [ "Original: " ++ orig
, "Encoded: " ++ enc
, "Decoded: " ++ dec ]</syntaxhighlight>
 
{{out}}
<pre style="font-size:80%">Original: One night-it was on the twentieth of March, 1888-I was returning
Encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
Decoded: ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
StraddlingCheckerBoard("setup","HOLMESRTABCDFGIJKNPQUVWXYZ./", 3,7)
 
Line 885 ⟶ 1,156:
}
}
end</langsyntaxhighlight>
 
Output:<pre>text = "One night. it was on the twentieth of March, 1888. I was returning"
Line 893 ⟶ 1,164:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">'Esc Stop'=: '/.'
'Nums Alpha'=: '0123456789';'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Charset=: Nums,Alpha,Stop
Line 917 ⟶ 1,188:
}.board {~ _2 (_&".)\ idx
end.
)</langsyntaxhighlight>
'''Example usage:'''
<langsyntaxhighlight lang="j"> preprocess=: (#~ Charset e.~ ])@toupper NB. verb to compress out non-alphanumerics
chkbrdRC=: chkbrd (3 7;'HOLMESRTABCDFGIJKNPQUVWXYZ./') NB. define adverb by applying Rosetta Code key to chkbrd conjunction
0 chkbrdRC preprocess 'One night-it was on the twentieth of March, 1888-I was returning'
139539363509369743061399059745399365901344308320791798798798367430685972839363935
1 chkbrdRC 0 chkbrdRC preprocess 'One night-it was on the twentieth of March, 1888-I was returning'
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</langsyntaxhighlight>
Or using the rules proposed by [[User:Util|Util]] on the discussion page:
<langsyntaxhighlight lang="j"> preprocess=: Stop&([`([: I. Charset -.@e.~ ])`]} toupper) NB. replace all non-alphanumerics with Stop
1 chkbrdRC 0 chkbrdRC preprocess 'One night-it was on the twentieth of March, 1888-I was returning'
ONE.NIGHT.IT.WAS.ON.THE.TWENTIETH.OF.MARCH..1888.I.WAS.RETURNING</langsyntaxhighlight>
 
 
Line 934 ⟶ 1,205:
 
'''Solution:'''
<langsyntaxhighlight lang="j">NB. stops setcode alphabet
NB. creates verbs encode and decode which change between unencoded text and lists of encoded numbers
setcode=: 3 :0
Line 950 ⟶ 1,221:
decode=: (alphabet {~ keys i. break f.) :. encode
i.0 0
)</langsyntaxhighlight>
 
'''Example usage:'''
<langsyntaxhighlight lang="j"> 3 7 setcode 'HOLMESRTABCDFGIJKNPQUVWXYZ./'
preprocess=: (#~ alphabet e.~ ])@toupper
,":"0 encode message=: preprocess 'One night-it was on the twentieth of March, 1888-I was returning'
Line 962 ⟶ 1,233:
OWVKRNEOAMTMXROWOHTMTMTROTQ4SEMRRLRZLVSTTLLOROMHALSFOHECMRWESWEE
((10|-) 0 4 5 2$~$)&.encode s
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|7}}
<langsyntaxhighlight lang="java">import java.util.MapHashMap;
import java.util.Map;
import java.util.regex.*;
 
Line 1,012 ⟶ 1,284:
return sb.toString();
}
}</langsyntaxhighlight>
 
<pre>139539363509369743061399059745399365901344308320791798798798367430685972839363935
Line 1,018 ⟶ 1,290:
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript"><script>
var alphabet=new Array("ESTONIA R","BCDFGHJKLM","PQUVWXYZ./") // scramble alphabet as you wish
var prefixes=new Array("",alphabet[0].indexOf(" "),alphabet[0].lastIndexOf(" "))
Line 1,058 ⟶ 1,330:
document.writeln(straddle(str))
document.writeln(unstraddle(straddle(str)))
</script></langsyntaxhighlight>
 
Output:<pre>One night-it was on the twentieth of March, 1888-I was returning.
34045747525284613427502840425027537379697175891898898898584619028294547488
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING.</pre>
 
=={{header|Julia}}==
Unlike the precomputed table versions, this version takes a 30-character string specifying the 3 rows of the checkerboard
as an argument, recomputing the lookup table each run, which allows easier changes of keys without modifying the code.
<syntaxhighlight lang="julia">
function straddlingcheckerboard(board, msg, doencode)
lookup = Dict()
reverselookup = Dict()
row2 = row3 = slash = -1
function encode(x)
s = ""
for ch in replace(replace(uppercase(x), r"([01-9])", s";=;\1"), r";=;", slash)
c = string(ch)
if haskey(lookup, c)
s *= lookup[c]
elseif contains("0123456789", c)
s *= c
end
end
s
end
function decode(x)
s = ""
i = 1
while i <= length(x)
c = string(x[i])
if haskey(reverselookup, c)
s *= reverselookup[c]
i += 1
else
if "$c$(x[i+1])" == slash
s *= string(x[i+2])
i += 3
else
s *= reverselookup["$c$(x[i+1])"]
i += 2
end
end
end
s
end
for (i,c) in enumerate(board)
c = string(c)
if c == " "
if row2 == -1
row2 = i-1
else
row3 = i-1
end
else
if i < 11
lookup[c] = "$(i-1)"; reverselookup["$(i-1)"] = c
elseif i < 21
lookup[c] = "$row2$(i-11)"; reverselookup["$row2$(i-11)"] = c
else
lookup[c] = "$row3$(i-21)"; reverselookup["$row3$(i-21)"] = c
end
if c == "/"
slash = lookup[c]
end
end
end
doencode ? encode(msg) : decode(msg)
end
 
btable = "ET AON RISBCDFGHJKLMPQ/UVWXYZ."
message = "Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour."
encoded = straddlingcheckerboard(btable, message, true)
decoded = straddlingcheckerboard(btable, encoded, false)
println("Original: $message\nEncoded: $encoded\nDecoded: $decoded")
</syntaxhighlight>
{{output}}
<pre>
Original: Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.
Encoded: 125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769
Decoded: THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.2.0
 
val board = "ET AON RISBCDFGHJKLMPQ/UVWXYZ."
val digits = "0123456789"
val rows = " 26"
val escape = "62"
val key = "0452"
 
fun encrypt(message: String): String {
val msg = message.toUpperCase()
.filter { (it in board || it in digits) && it !in " /" }
val sb = StringBuilder()
for (c in msg) {
val idx = board.indexOf(c)
if (idx > -1) {
val row = idx / 10
val col = idx % 10
sb.append(if (row == 0) "$col" else "${rows[row]}$col")
}
else {
sb.append("$escape$c")
}
}
val enc = sb.toString().toCharArray()
for ((i, c) in enc.withIndex()) {
val k = key[i % 4] - '0'
if (k == 0) continue
val j = c - '0'
enc[i] = '0' + ((j + k) % 10)
}
return String(enc)
}
 
fun decrypt(encoded: String): String {
val enc = encoded.toCharArray()
for ((i, c) in enc.withIndex()) {
val k = key[i % 4] - '0'
if (k == 0) continue
val j = c - '0'
enc[i] = '0' + if (j >= k) (j - k) % 10 else (10 + j - k) % 10
}
val len = enc.size
val sb = StringBuilder()
var i = 0
while (i < len) {
val c = enc[i]
val idx = rows.indexOf(c)
if (idx == -1) {
val idx2 = c - '0'
sb.append(board[idx2])
i++
}
else if ("$c${enc[i + 1]}" == escape) {
sb.append(enc[i + 2])
i += 3
}
else {
val idx2 = idx * 10 + (enc[i + 1] - '0')
sb.append(board[idx2])
i += 2
}
}
return sb.toString()
}
 
fun main(args: Array<String>) {
val messages = listOf(
"Attack at dawn",
"One night-it was on the twentieth of March, 1888-I was returning",
"In the winter 1965/we were hungry/just barely alive",
"you have put on 7.5 pounds since I saw you.",
"The checkerboard cake recipe specifies 3 large eggs and 2.25 cups of flour."
)
for (message in messages) {
val encrypted = encrypt(message)
val decrypted = decrypt(encrypted)
println("\nMessage : $message")
println("Encrypted : $encrypted")
println("Decrypted : $decrypted")
}
}</syntaxhighlight>
 
{{out}}
<pre>
Message : Attack at dawn
Encrypted : 3565257935743007
Decrypted : ATTACKATDAWN
 
Message : One night-it was on the twentieth of March, 1888-I was returning
Encrypted : 495786945533698149645468540384645875238925776668221480708005915367278976
Decrypted : ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
 
Message : In the winter 1965/we were hungry/just barely alive
Encrypted : 89645417896270736648201450026959060839767024608116557470618482160
Decrypted : INTHEWINTER1965WEWEREHUNGRYJUSTBARELYALIVE
 
Message : you have put on 7.5 pounds since I saw you.
Encrypted : 61983605685800834914704829124087264189730245691940889
Decrypted : YOUHAVEPUTON7.5POUNDSSINCEISAWYOU.
 
Message : The checkerboard cake recipe specifies 3 large eggs and 2.25 cups of flour.
Encrypted : 160225770664742408892673362274738052905225343251668487244454469139746678907466041088039436848815704
Decrypted : THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.
</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">
local brd = { "HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./" }
local dicE, dicD, s1, s2 = {}, {}, 0, 0
Line 1,138 ⟶ 1,593:
-- entry point
enterText()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,158 ⟶ 1,613:
</pre>
 
=={{header|PerlM2000 6Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
The .trans method in Perl 6 improves on Perl 5's tr/// by allowing multi-character translation tables.
module Straddling_checkerboard {
function encrypt$(message$, alphabet) {
message$=filter$(ucase$(message$),"-/,. ")
def num1, num2
num1=instr(alphabet#val$(0)," ")
num2=instr(alphabet#val$(0)," ", num1+1)-1
num1--
escapenum=instr(alphabet#val$(2),"/")-1
escapenum1=instr(alphabet#val$(2),".")-1
num0=-10
num10=num1*10-20
num20=num2*10-30
numbers=(escapenum+num2*10)*10
numbers1=(escapenum1+num2*10)*10
boardrow=each(alphabet)
cipherkey$="0123456789" : while boardrow :cipherkey$+=array$(boardrow) :end while
encoded$=""
for i=1 to len(message$)
n=instr(cipherkey$, mid$(message$,i,1))-1
if n<10 then
n+=if(random(10)<5->numbers, numbers1)
else.if n<20 then
n+=num0
else.if n<30 then
n+=num10
else
n+=num20
end if
encoded$+=str$(n,"")
next
=encoded$
}
function decrypt$(encoded$, alphabet) {
def num1, num2
num1=instr(alphabet#val$(0)," ")
num2=instr(alphabet#val$(0)," ", num1+1)-1
num1--
escapenum=instr(alphabet#val$(2),"/")-1
escapenum1=instr(alphabet#val$(2),".")-1
def i=1, decoded$
j=len(encoded$)+1
while i<j
m=val(mid$(encoded$,i,1))
if m=num1 then
decoded$+=mid$(alphabet#val$(1), val(mid$(encoded$,i+1,1))+1,1)
i++
else.if m=num2 then
if i+1<j then
mm=val(mid$(encoded$,i+1,1))
if mm=escapenum or mm=escapenum1 then
decoded$+=mid$(encoded$,i+2,1)
i+=2
else
decoded$+=mid$(alphabet#val$(2), val(mid$(encoded$,i+1,1))+1,1)
i++
end if
else
decoded$+=mid$(alphabet#val$(2), val(mid$(encoded$,i+1,1))+1,1)
i++
end if
else
decoded$+=mid$(alphabet#val$(0), m+1,1)
end if
i++
end while
=decoded$
}
Module DisplayBoard (alphabet, &Doc$){
num1=instr(alphabet#val$(0)," ")
num2=instr(alphabet#val$(0)," ", num1+1)-1
num1--
escapenum=instr(alphabet#val$(2),"/")-1
escapenum1=instr(alphabet#val$(2),".")-1
\\ display straddling checkerboard
checkerboard =cons(("0123456789",),alphabet)
labels=(" "," ",str$(num1,""), str$(num2,""))
disp=each(checkerboard)
while disp
Doc$=labels#val$(disp^)+" "+array$(disp)+{
}
end while
}
Document Doc$
Const nl$={
}
Function OnePad$(Message$, PadSerial, n=1) {
x=random(!PadSerial) ' push old seed, set the new one
encoded$=""
for i=1 to len(Message$)
encoded$+=str$((val(mid$(Message$,i,1))+10+n*random(1, 10))mod 10,"")
next i
x=random(!) ' restore old seed
=encoded$
}
\\ select a random alphabet
select case random(1,3)
case 1
alphabet=("ESTONIAR ","BCDFGHJKLM","/PQUVWXYZ.") : Doc$="First "+nl$
case 2
alphabet=("ET AON RIS","BCDFGHJKLM","PQ/UVWXYZ.") : Doc$="Second"+nl$
case 3
alphabet=("ESTONIAR ","BCDFGHJKLM","PQU.VWXYZ/") : Doc$="Third"+nl$
end select
DisplayBoard alphabet, &Doc$
msg$="One night-it was on the twentieth of March, 1888-I was returning"
Doc$= "original message:"+nl$
Doc$= msg$+nl$
Doc$= "encrypted message:"+nl$
crypt$=encrypt$(msg$, alphabet)
Doc$=crypt$+nl$
serial=random(1234567,9345678)
Doc$= "encrypted message using one pad using serial:"+str$(serial)+nl$
crypt$=OnePad$(crypt$, serial)
Doc$=crypt$+nl$
Doc$= "decrypted message using one pad:"+nl$
crypt$=OnePad$(crypt$, serial,-1)
Doc$=crypt$+nl$
Doc$= "decrypted message:"+nl$
Doc$=decrypt$(crypt$, alphabet)
Print #-2, Doc$ ' render to console using new lines codes from Doc$
Clipboard Doc$
}
Straddling_checkerboard
</syntaxhighlight>
 
{{out}}
We build the full table during .new, which simplifies .encode and .decode.
<pre style="height:30ex;overflow:scroll">
<lang perl6>class Straddling_Checkerboard {
First
has @!flat_board; # 10x3 stored as 30x1
0123456789
has $!plain2code; # Full translation table; invertable
ESTONIAR
has @!table; # Printable layout, like Wikipedia entry
8 BCDFGHJKLM
9 /PQUVWXYZ.
my $numeric_escape = '/';
original message:
my $exclude = /<-[A..Z0..9.]>/; # Omit the escape character
One night-it was on the twentieth of March, 1888-I was returning
encrypted message:
340458485252956134285029504250285383896781859019989989985956170293745484
encrypted message using one pad using serial: 7745037
811354381526409435575275634030693156335135381796263056259799033307312819
decrypted message using one pad:
340458485252956134285029504250285383896781859019989989985956170293745484
decrypted message:
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
Second
0123456789
ET AON RIS
2 BCDFGHJKLM
6 PQ/UVWXYZ.
original message:
One night-it was on the twentieth of March, 1888-I was returning
encrypted message:
450582425181653945125016505180125423293721256216986986288653970163758524
encrypted message using one pad using serial: 8485713
339360039726873741044731817004082441136155821888897367354417518371636266
decrypted message using one pad:
450582425181653945125016505180125423293721256216986986288653970163758524
decrypted message:
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</pre >
 
=={{header|Nim}}==
method display_table { say ~ .list for @!table };
I used the same example as in the Go solution (and, fortunately, got the same result).
<syntaxhighlight lang="nim">import strutils, tables
 
const
method decode ( Str $s --> Str ) {
FullStop = '.'
$s.trans($!plain2code.invert);
Escape = }'/'
 
type Checkerboard = object
method encode ( Str $s, :$collapse? --> Str ) {
encryptTable: Table[char, string]
my $replace = $collapse ?? '' !! '.';
decryptTable: Table[string, char]
$s.uc.subst( $exclude, $replace, :g ).trans($!plain2code);
}
 
submethod BUILD ( :$alphabet, :$u where 0..9, :$v where 0..9 ) {
die if $u == $v;
die if $alphabet.comb.sort.join ne [~] './', 'A'..'Z';
 
proc initCheckerboard(digits: string; row1, row2, row3: string): Checkerboard =
@!flat_board = $alphabet.uc.comb;
## Initialize a checkerboard with given digits in row 0 and the following given rows.
@!flat_board.splice( $u min $v, 0, Any );
## No sanity check is performed.
@!flat_board.splice( $u max $v, 0, Any );
 
var rowChars: seq[char] # The two characters to use to identify rows 2 and 3.
@!table = [ ' ', [ 0 .. 9] ],
[ ' ', @!flat_board[ 0 .. 9].map: * // ' ' ],
[ $u, @!flat_board[10 .. 19] ],
[ $v, @!flat_board[20 .. 29] ];
 
# Process row 1.
my @order = 0..9; # This may be passed as a param in the future
for col, ch in row1:
if ch == ' ':
rowChars.add digits[col]
else:
result.encryptTable[ch] = $digits[col]
if rowChars.len != 2:
raise newException(ValueError, "expected two blank spots in first letter row.")
 
# Add rows 2 and 3.
my @nums = @order,
for col, ch in row2:
@order.map({ +"$u$_" }),
result.encryptTable[ch] = rowChars[0] & digits[col]
@order.map({ +"$v$_" });
for col, ch in row3:
result.encryptTable[ch] = rowChars[1] & digits[col]
if Escape notin result.encryptTable:
raise newException(ValueError, "missing Escape character.")
 
# Build decrypt table from encrypt table.
my %p2c = @!flat_board Z=> @nums;
for c, s in result.encryptTable.pairs:
%p2c.delete(Any);
result.decryptTable[s] = c
%p2c{$_} = %p2c{$numeric_escape} ~ $_ for 0..9;
 
 
$!plain2code = [%p2c.keys] => [%p2c.values];
proc encrypt(board: Checkerboard; message: string): string =
## Encrypt a string.
 
let message = message.toUpperAscii
for ch in message:
case ch
of 'A'..'Z', FullStop, Escape:
result.add board.encryptTable[ch]
of '0'..'9':
result.add board.encryptTable[Escape]
result.add ch
else:
discard # Ignore other characters.
 
 
proc raiseError() =
## Raise a ValueError to signal a corrupt message.
raise newException(ValueError, "corrupt message")
 
 
proc decrypt(board: Checkerboard; message: string): string =
## Decrypt a message.
 
var escaped = false # Escape char previously encountered.
var str = "" # Current sequence of characters (contains 0, 1 or 2 chars).
 
for ch in message:
if ch notin '0'..'9': raiseError()
 
if escaped:
# Digit is kept as is.
result.add ch
escaped = false
else:
# Try to decrypt this new digit.
str.add ch
if str in board.decryptTable:
let c = board.decryptTable[str]
if c == Escape: escaped = true
else: result.add c
str.setLen(0)
elif str.len == 2:
# Illegal combination of two digits.
raiseError()
 
when isMainModule:
let board = initCheckerboard("8752390146", "ET AON RIS", "BC/FGHJKLM", "PQD.VWXYZU")
let message = "you have put on 7.5 pounds since I saw you."
echo "Message: ", message
let crypted = board.encrypt(message)
echo "Crypted: ", crypted
echo "Decrypted: ", board.decrypt(crypted)</syntaxhighlight>
 
{{out}}
<pre>Message: you have put on 7.5 pounds since I saw you.
Crypted: 01306592038080673955702555083069056649578462090130602
Decrypted: YOUHAVEPUTON7.5POUNDSSINCEISAWYOU.</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use List::Util <min max>;
 
my(%encode,%decode,@table);
 
sub build {
my($u,$v,$alphabet) = @_;
my(@flat_board,%p2c,%c2p);
my $numeric_escape = '/';
 
@flat_board = split '', uc $alphabet;
splice @flat_board, min($u,$v), 0, undef;
splice @flat_board, max($u,$v), 0, undef;
 
push @table, [' ', 0..9];
push @table, [' ', map { defined $_ ? $_ : ' '} @flat_board[ 0 .. 9] ];
push @table, [$u, @flat_board[10 .. 19]];
push @table, [$v, @flat_board[20 .. 29]];
 
my @nums = my @order = 0..9;
push @nums, (map { +"$u$_" } @order), map { +"$v$_" } @order;
 
@c2p{@nums} = @flat_board;
for (keys %c2p) { delete $c2p{$_} unless defined $c2p{$_} }
@p2c{values %c2p} = keys %c2p;
$p2c{$_} = $p2c{$numeric_escape} . $_ for 0..9;
while (my ($k, $v) = each %p2c) {
$encode{$k} = $v;
$decode{$v} = $k unless $k eq $numeric_escape;
}
}
 
sub decode {
sub MAIN ( :$u = 3, :$v = 7, :$alphabet = 'HOLMESRTABCDFGIJKNPQUVWXYZ./' ) {
my($string) = @_;
my Straddling_Checkerboard $sc .= new: :$u, :$v, :$alphabet;
my $keys = join '|', keys %decode;
$sc.display_table;
$string =~ s/($keys)/$decode{$1}/gr;
}
 
sub encode {
for 0..1 -> $collapse {
my($string) = uc shift;
my $original = 'One night-it was on the twentieth of March, 1888-I was returning';
my $enstring =~ s#(.)#$sc.encode({$original,1} // :$collapse)encode{'.'}#ger;
}
my $de = $sc.decode($en);
say;
say "Original: $original";
say "Encoded: $en";
say "Decoded: $de";
}
}</lang>
 
my $sc = build(3, 7, 'HOLMESRTABCDFGIJKNPQUVWXYZ./');
Output:<pre> 0 1 2 3 4 5 6 7 8 9
say join ' ', @$_ for @table;
say '';
say 'Original: ', my $original = 'One night-it was on the twentieth of March, 1888-I was returning';
say 'Encoded: ', my $en = encode($original);
say 'Decoded: ', decode($en);</syntaxhighlight>
{{out}}
<pre> 0 1 2 3 4 5 6 7 8 9
H O L M E S R T
3 A B C D F G I J K N
Line 1,230 ⟶ 1,934:
Original: One night-it was on the twentieth of March, 1888-I was returning
Encoded: 13957839363509783697874306781397890578974539936590781347843083207878791798798798783678743067885972839363935
Decoded: ONE.NIGHT.IT.WAS.ON.THE.TWENTIETH.OF.MARCH..1888.I.WAS.RETURNING</pre>
 
=={{header|Phix}}==
Original: One night-it was on the twentieth of March, 1888-I was returning
{{trans|C}}
Encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
<!--<syntaxhighlight lang="phix">(phixonline)-->
Decoded: ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</pre>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">read_table</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">cb</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">encode</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">128</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">decode</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">128</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">row</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cb</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">30</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"table wrong length"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">30</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cb</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">row</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #008080;">else</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">code</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">10</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">((</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">encode</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">code</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">decode</span><span style="color: #0000FF;">[</span><span style="color: #000000;">code</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">encode</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">encipher</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">strip</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]),</span> <span style="color: #000000;">code</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">[</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">c</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'Z'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">elsif</span> <span style="color: #008080;">not</span> <span style="color: #000000;">strip</span> <span style="color: #008080;">or</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'/'</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (see note)</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">[</span><span style="color: #008000;">'/'</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">decipher</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">strip</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">10</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'/'</span> <span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #000000;">strip</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (see note)</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">' '</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">d</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">cb</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"ET AON RIS"</span><span style="color: #0000FF;">&</span>
<span style="color: #008000;">"BCDFGHJKLM"</span><span style="color: #0000FF;">&</span>
<span style="color: #008000;">"PQ/UVWXYZ."</span>
<span style="color: #004080;">sequence</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">encode</span><span style="color: #0000FF;">,</span><span style="color: #000000;">decode</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cb</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- Note there is a subtle difference in space handling, to exactly match other outputs try
-- {encode,decode} = read_table("HOL MES RTABCDFGIJKNPQUVWXYZ/.") instead of
-- {encode,decode} = read_table("HOL MES RTABCDFGIJKNPQUVWXYZ./"), and
-- {encode,decode} = read_table("ET AON RISBCDFGHJKLMPQ.UVWXYZ/") instead of
-- {encode,decode} = read_table("ET AON RISBCDFGHJKLMPQ/UVWXYZ.")</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"In the winter 1965/we were hungry/just barely alive"</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"message: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">enc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">encipher</span><span style="color: #0000FF;">(</span><span style="color: #000000;">encode</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">dec</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">decipher</span><span style="color: #0000FF;">(</span><span style="color: #000000;">decode</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">enc</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"encoded: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"decoded: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">dec</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nNo spaces:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">enc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">encipher</span><span style="color: #0000FF;">(</span><span style="color: #000000;">encode</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dec</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">decipher</span><span style="color: #0000FF;">(</span><span style="color: #000000;">decode</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">enc</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"encoded: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"decoded: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">dec</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
message: In the winter 1965/we were hungry/just barely alive
encoded: 85621250626585107626916996966956265062650706225635247676226639162203702867623288640
decoded: IN THE WINTER 1965 WE WERE HUNGRY JUST BARELY ALIVE
 
No spaces:
encoded: 851250658510769169969669562650650702563524767622663912037028673288640
decoded: INTHEWINTER1965/WEWEREHUNGRY/JUSTBARELYALIVE
</pre>
 
=={{header|PHP}}==
{{trans|Java}}
{{works with|PHP 7}}
<syntaxhighlight lang="php">$key2val = ["A"=>"30", "B"=>"31", "C"=>"32", "D"=>"33", "E"=>"5", "F"=>"34", "G"=>"35",
"H"=>"0", "I"=>"36", "J"=>"37", "K"=>"38", "L"=>"2", "M"=>"4", "."=>"78", "N"=>"39",
"/"=>"79", "O"=>"1", "0"=>"790", "P"=>"70", "1"=>"791", "Q"=>"71", "2"=>"792",
"R"=>"8", "3"=>"793", "S"=>"6", "4"=>"794", "T"=>"9", "5"=>"795", "U"=>"72",
"6"=>"796", "V"=>"73", "7"=>"797", "W"=>"74", "8"=>"798", "X"=>"75", "9"=>"799",
"Y"=>"76", "Z"=>"77"];
$val2key = array_flip($key2val);
 
function encode(string $s) : string {
global $key2val;
$callback = function($c) use ($key2val) { return $key2val[$c] ?? ''; };
 
return implode(array_map($callback, str_split(strtoupper($s))));
}
function decode(string $s) : string {
global $val2key;
 
$callback = function($c) use ($val2key) { return $val2key[$c] ?? ''; };
preg_match_all('/79.|7.|3.|./', $s, $m);
return implode(array_map($callback, $m[0]));
}
 
function main($s) {
$encoded = encode($s);
echo $encoded;
echo "\n";
echo decode($encoded);
}
 
main('One night-it was on the twentieth of March, 1888-I was returning');</syntaxhighlight>
<pre>
139539363509369743061399059745399365901344308320791798798798367430685972839363935
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de *Straddling
(NIL "H" "O" "L" NIL "M" "E" "S" NIL "R" "T")
("3" "A" "B" "C" "D" "F" "G" "I" "J" "K" "N")
Line 1,264 ⟶ 2,101:
(get (cdr @) (inc (format (pop 'L))))
(get (cdar *Straddling) (inc (format C))) ) )
(link (if (= "/" C) (pop 'L) C)) ) ) ) ) )</langsyntaxhighlight>
Output:
<pre>: (straddle "One night-it was on the twentieth of March, 1888-I was returning")
Line 1,271 ⟶ 2,108:
: (unStraddle @)
-> "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING"</pre>
 
=={{header|PureBasic}}==
<langsyntaxhighlight lang="purebasic">Procedure.s encrypt_SC(originalText.s, alphabet.s, blank_1, blank_2)
Static notEscape.s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ."
Protected preDigit_1.s = Str(blank_1), preDigit_2.s = Str(blank_2)
Line 1,367 ⟶ 2,205:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>Original: One night-it was on the twentieth of March, 1888-I was returning
Line 1,376 ⟶ 2,214:
=={{header|Python}}==
Partially based on the PicoLisp version:
<langsyntaxhighlight lang="python">T = [["79", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
["", "H", "O", "L", "", "M", "E", "S", "", "R", "T"],
["3", "A", "B", "C", "D", "F", "G", "I", "J", "K", "N"],
Line 1,396 ⟶ 2,234:
O = "One night-it was on the twentieth of March, 1888-I was returning"
print "Encoded:", straddle(O)
print "Decoded:", "".join(unstraddle(straddle(O)))</langsyntaxhighlight>
Output:
<pre>Encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
Line 1,405 ⟶ 2,243:
 
We store the straddling checkerboard in a structure, so it can be reused or changed for the different examples. The “constructor” transforms the lines of the checkboard into an internal representation.
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(struct *straddling (header main original)
Line 1,433 ⟶ 2,271:
(*straddling (list->vector (list* "?" "" header-tail)) main lines))
(define escape (straddling-encode-char #\/ temporal-board))
(*straddling (list->vector (list* escape "" header-tail)) main lines))</langsyntaxhighlight>
Now we define the functions to straddle and unstraddle the message.
<langsyntaxhighlight Racketlang="racket">(define (straddling-encode-char char board)
(or (for/or ([head (in-vector (*straddling-header board))]
[line (in-vector (*straddling-main board))])
Line 1,474 ⟶ 2,312:
(values #f (cons decoded rev-ret))))))])
(unless row ;check that last number was not missing
rev-ret)))))</langsyntaxhighlight>
'''Two examples:'''
<langsyntaxhighlight Racketlang="racket">(define (test-straddling message board)
(let* ([encoded (straddle message board)]
[decoded (unstraddle encoded board)])
Line 1,492 ⟶ 2,330:
(straddling "ET AON RIS"
"BCDFGHJKLM"
"PQ/UVWXYZ."))</langsyntaxhighlight>
{{out}}
<pre>#<straddling ("HOL MES RT" "ABCDFGIJKN" "PQUVWXYZ./")>
Line 1,503 ⟶ 2,341:
450582425181653945125016505180125423293721256216286286288653970163758524
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
The .trans method in Raku improves on Perl 5's tr/// by allowing multi-character translation tables.
 
We build the full table during .new, which simplifies .encode and .decode.
<syntaxhighlight lang="raku" line>class Straddling_Checkerboard {
has @!flat_board; # 10x3 stored as 30x1
has $!plain2code; # full translation table, invertable
has @!table; # Printable layout, like Wikipedia entry
my $numeric_escape = '/';
my $exclude = /<-[A..Z0..9.]>/; # Omit the escape character
 
method display_table { gather { take ~ .list for @!table } };
 
method decode ( Str $s --> Str ) {
$s.trans($!plain2code.antipairs);
}
 
method encode ( Str $s, :$collapse? --> Str ) {
my $replace = $collapse ?? '' !! '.';
$s.uc.subst( $exclude, $replace, :g ).trans($!plain2code);
}
 
submethod BUILD ( :$alphabet, :$u where 0..9, :$v where 0..9 ) {
die if $u == $v;
die if $alphabet.comb.sort.join ne [~] flat './', 'A'..'Z';
 
@!flat_board = $alphabet.uc.comb;
@!flat_board.splice( $u min $v, 0, Any );
@!flat_board.splice( $u max $v, 0, Any );
 
@!table = [ ' ',| [ 0 .. 9] ],
[ ' ',|@!flat_board[ 0 .. 9].map: {.defined ?? $_ !! ' '} ],
[ $u, |@!flat_board[10 .. 19] ],
[ $v, |@!flat_board[20 .. 29] ];
 
my @order = 0..9; # This may be passed as a param in the future
 
my @nums = flat @order,
@order.map({ +"$u$_" }),
@order.map({ +"$v$_" });
 
my %c2p = @nums Z=> @!flat_board;
%c2p{$_}:delete if %c2p{$_} eqv Any for keys %c2p;
my %p2c = %c2p.invert;
%p2c{$_} = %p2c{$numeric_escape} ~ $_ for 0..9;
$!plain2code = [%p2c.keys] => [%p2c.values];
}
}
 
sub MAIN ( :$u = 3, :$v = 7, :$alphabet = 'HOLMESRTABCDFGIJKNPQUVWXYZ./' ) {
my Straddling_Checkerboard $sc .= new: :$u, :$v, :$alphabet;
$sc.display_table;
 
for 0..1 -> $collapse {
my $original = 'One night-it was on the twentieth of March, 1888-I was returning';
my $en = $sc.encode($original, :$collapse);
my $de = $sc.decode($en);
say '';
say "Original: $original";
say "Encoded: $en";
say "Decoded: $de";
}
}</syntaxhighlight>
 
Output:<pre> 0 1 2 3 4 5 6 7 8 9
H O L M E S R T
3 A B C D F G I J K N
7 P Q U V W X Y Z . /
 
Original: One night-it was on the twentieth of March, 1888-I was returning
Encoded: 13957839363509783697874306781397890578974539936590781347843083207878791798798798783678743067885972839363935
Decoded: ONE.NIGHT.IT.WAS.ON.THE.TWENTIETH.OF.MARCH..1888.I.WAS.RETURNING
 
Original: One night-it was on the twentieth of March, 1888-I was returning
Encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
Decoded: ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING</pre>
 
=={{header|REXX}}==
Extra coding was added to:
:* &nbsp; allow the use of any table &nbsp; (specifiable on the invocation of the &nbsp; '''genCipher''' &nbsp; subroutine, the 5<sup>th</sup> line in the REXX program),
:* &nbsp; no hard-coding of the location of blanks,
:* &nbsp; no hard-coding or the numbered lines in the straddled checkerboard table,
:* &nbsp; no hard-coding of the location of the escape character,
:* &nbsp; support the usage of a blank in the 1<sup>st</sup> character (the top line of the table).
<syntaxhighlight lang="rexx">/*REXX program uses the straddling checkerboard cipher to encrypt/decrypt a message. */
parse arg msg /*obtain optional message from the C.L.*/
if msg='' then msg= 'One night-it was the twentieth of March, 1888-I was returning'
say 'plain text=' msg
call genCipher 'et aon ris', 'bcdfghjklm', 'pq/uvwxyz.' /*build the cipher (board)*/
enc= encrypt(msg); say ' encrypted=' enc /*encrypt message and show encryption. */
dec= decrypt(enc); say ' decrypted=' dec /*decrypt " " " decryption. */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
genCipher: @.=; arg @..,two,three; z= -1; @.z= @.. /*build top row of cipher.*/
_= pos(' ', @.. ) - 1; @._= two /* " 2nd " " " */
_= pos(' ', @.., _+2) - 1; @._= three /* " 3rd " " " */
do j=0 for 9; @..= @.. || @.j /*construct a table for fast searching.*/
if @.j\=='' then @.r= @.r || j
_= pos('/', @.j) /*is the escape character in this row? */
if _\==0 then @.dig= j || (_-1) /*define " " for numerals.*/
end /*j*/
@..= space(@.., 0); return /*purify the table of encryptable chars*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
encrypt: procedure expose @.; arg !,,$ /*$: output (encrypted text) so far.*/
do j=1 for length(!) /*process each of the plain─text chars.*/
x= substr(!, j, 1) /*obtain a message char to be encrypted*/
if datatype(x, 'W') then do; $= $ || @.dig || x; iterate; end /*numeral?*/
if pos(x, @..)==0 then iterate /*Not one of the allowable chars? Skip*/
do k=-1 for 10; y= pos(x, @.k) /*traipse thru rows, looking for match.*/
if y==0 then iterate /*Not in this row? Then keep looking.*/
z= k; if z==-1 then z= /*construct the index of the cypher row*/
$= $ || z || (y-1); leave /*add an encrypted character to output.*/
end /*k*/
end /*j*/; return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
decrypt: procedure expose @.; parse arg !,,$ /*$: output (decrypted text) so far.*/
do j=1 to length(!); rw= -1 /*process each of the encypted numbers.*/
x= substr(!,j,1) /*obtain a message char to be decrypted*/
if substr(!,j,2)==@.dig then do; j= j+2; $= $ || substr(!, j, 1); iterate; end
if pos(x, @.r)\==0 then do; j= j+1; rw=x; x=substr(!, j, 1); end
$= $ || substr(@.rw, x+1, 1) /*add a character to decrypted message.*/
end /*j*/; return $</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
plain text= One night-it was the twentieth of March, 1888-I was returning
encrypted= 4505824251816539125016505180125423293721256216286286288653970163758524
decrypted= ONENIGHTITWASTHETWENTIETHOFMARCH1888IWASRETURNING
</pre>
 
=={{header|Ruby}}==
{{works with|Ruby|2.0}}
<langsyntaxhighlight lang="ruby">class StraddlingCheckerboard
EncodableChars = "A-Z0-9."
SortedChars = " ./" + [*"A".."Z"].join
Line 1,566 ⟶ 2,536:
"#<%s board=%p, row_labels=%p, mapping=%p>" % [self.class, to_s, @row_labels, @mapping]
end
end</langsyntaxhighlight>
 
The test suite
<langsyntaxhighlight lang="ruby">require 'test/unit'
class StraddlingCheckerboardTest < Test::Unit::TestCase
def setup
Line 1,608 ⟶ 2,578:
assert_raise(ArgumentError) {StraddlingCheckerboard.new "ET ON RISBCDFGHJKLMPQ/UVWXYZ.!"}
end
end</langsyntaxhighlight>
 
output
Line 1,624 ⟶ 2,594:
 
4 tests, 5 assertions, 0 failures, 0 errors, 0 skips</pre>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/xCHsvaC/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/42qQPkm6TiONpAOC1ByTCg Scastie (remote JVM)].
<syntaxhighlight lang="scala">object StraddlingCheckerboard extends App {
 
private val dictonary = Map("H" -> "0", "O" -> "1",
"L" -> "2", "M" -> "4", "E" -> "5", "S" -> "6", "R" -> "8", "T" -> "9",
"A" -> "30", "B" -> "31", "C" -> "32", "D" -> "33", "F" -> "34", "G" -> "35",
"I" -> "36", "J" -> "37", "K" -> "38", "N" -> "39", "P" -> "70", "Q" -> "71",
"U" -> "72", "V" -> "73", "W" -> "74", "X" -> "75", "Y" -> "76", "Z" -> "77",
"." -> "78", "/" -> "79", "0" -> "790", "1" -> "791", "2" -> "792", "3" -> "793",
"4" -> "794", "5" -> "795", "6" -> "796", "7" -> "797", "8" -> "798", "9" -> "799")
 
private def encode(s: String) =
s.toUpperCase.map { case ch: Char => dictonary.getOrElse(ch.toString, "") }.mkString
 
private def decode(s: String) = {
val revDictionary: Map[String, String] = dictonary.map {case (k, v) => (v, k)}
 
val pat = "(79.|3.|7.|.)".r
pat.findAllIn(s).map { el => revDictionary.getOrElse(el, "")}.addString(new StringBuilder)
}
 
val enc = encode(
"One night-it was on the twentieth of March, " + "1888-I was returning"
)
println(enc)
println(decode(enc))
}</syntaxhighlight>
 
=={{header|Tcl}}==
Structured as a class, the instances of which contain encoding and decoding mappings suitable for use with Tcl's built in string remapping engine. This uses the fact that no sequence of digits in the encoded form that maps to one character is a prefix of the sequence for any other character. (Inspired by the ''description'' of the [[#Perl 6Raku|Perl 6Raku]] solution.)<!--not a translation though; I didn't read the perl6Raku code…-->
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create StraddlingCheckerboardCypher {
Line 1,662 ⟶ 2,661:
string map $decmap [regsub -all {[^0-9]} $msg ""]
}
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">StraddlingCheckerboardCypher create demo {
{{} E T {} A O N {} R I S}
{2 B C D F G H J K L M}
Line 1,674 ⟶ 2,673:
puts "Input: $input"
puts "Encoded: $encrypted"
puts "Decoded: $output"</langsyntaxhighlight>
Output:
<pre>
Line 1,680 ⟶ 2,679:
Encoded: 450582425181653945125016505180125423293721256216286286288653970163758524
Decoded: ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</pre>
 
=={{header|VBScript}}==
{{trans|PureBasic}}
<syntaxhighlight lang="vb">' Straddling checkerboard - VBScript - 19/04/2019
 
Function encrypt(ByVal originalText, ByVal alphabet, blank1, blank2)
Const notEscape = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ."
Dim i, j, curChar, escChar, outText
Dim cipher 'Hash table
Set cipher = CreateObject("Scripting.Dictionary")
'build cipher reference
alphabet = UCase(alphabet) : j = 0
For i = 1 To 28
curChar = Mid(alphabet, i, 1)
Select Case True
Case i>= 1 And i<= 8
If j = blank1 Or j = blank2 Then j = j + 1 'adjust for blank
cipher.Add curChar, CStr(j)
j = j + 1
Case i>= 9 And i<=18
cipher.Add curChar, CStr(blank1) & CStr(i - 9)
Case i>=19 And i<=28
cipher.Add curChar, CStr(blank2) & CStr(i - 19)
End Select 'i
If InStr(notEscape, curChar) = 0 Then
escChar = curChar
'Wscript.Echo "escChar=" & escChar & " cipher(escChar)=" & cipher(escChar)
End If
Next 'i
For i = 0 To 9: cipher.Add CStr(i), cipher(escChar) & CStr(i): Next
'encrypt each character
originalText = UCase(originalText)
For i = 1 To Len(originalText)
outText = outText & cipher(Mid(originalText, i, 1))
Next
encrypt=outText
End Function 'encrypt
Function decrypt(ByVal cipherText, ByVal alphabet, blank1, blank2)
Const notEscape = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ."
Dim i, j, curChar, escCipher, outText
Dim cipher 'Hash table
Set cipher = CreateObject("Scripting.Dictionary")
'build decipher reference
alphabet = UCase(alphabet) : j = 0
For i = 1 To 28
curChar = Mid(alphabet, i, 1)
Select Case True
Case i>= 1 And i<= 8
If j = blank1 Or j = blank2 Then j = j + 1 'adjust for blank
cipher.Add CStr(j),curChar
j = j + 1
Case i>= 9 And i<=18
cipher.Add CStr(blank1) & CStr(i - 9), curChar
Case i>=19 And i<=28
cipher.Add CStr(blank2) & CStr(i - 19), curChar
End Select 'i
If InStr(notEscape, curChar) = 0 Then
'the last element of cipher
arrayKeys=cipher.keys
escCipher = arrayKeys(cipher.count-1)
'Wscript.Echo "escCipher=" & escCipher & " cipher(escCipher)=" & cipher(escCipher)
End If
Next 'i
For i = 0 To 9: cipher.Add escCipher & CStr(i), CStr(i): Next
'decrypt each character
i = 1
Do While i <= Len(cipherText)
curChar = Mid(cipherText, i, 1)
If curChar = CStr(blank1) Or curChar = CStr(blank2) Then
curChar = Mid(cipherText, i, 2)
If curChar = escCipher Then curChar = Mid(cipherText, i, 3)
End If
outText = outText & cipher(curChar)
i = i + Len(curChar)
Loop 'i
decrypt=outText
End Function 'decrypt
message = "One night-it was on the twentieth of March, 1888-I was returning"
cipher = "HOLMESRTABCDFGIJKNPQUVWXYZ./"
'3 7 <=8
'HOL MES RT
'ABCDFGIJKN
'PQUVWXYZ./
Buffer=Buffer & "Original: " & message & vbCrlf
encoded = encrypt(message, cipher, 3, 7)
Buffer=Buffer & "encoded: " & encoded & vbCrlf
decoded = decrypt(encoded, cipher, 3, 7)
Buffer=Buffer & "decoded: " & decoded & vbCrlf
Wscript.Echo Buffer </syntaxhighlight>
{{out}}
<pre>
Original: One night-it was on the twentieth of March, 1888-I was returning
encoded: 139539363509369743061399059745399365901344308320791798798798367430685972839363935
decoded: ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "./str" for Str
 
var board = "ET AON RISBCDFGHJKLMPQ/UVWXYZ."
var digits = "0123456789"
var rows = " 26"
var escape = "62"
var key = "0452"
 
var encrypt = Fn.new { |message|
var msg = Str.upper(message).
where { |c| (board.contains(c) || digits.contains(c)) && !" /".contains(c) }.join()
var sb = ""
for (c in msg) {
var idx = board.indexOf(c)
if (idx > -1) {
var row = (idx/10).floor
var col = idx % 10
sb = sb + ((row == 0) ? "%(col)" : "%(rows[row])%(col)")
} else {
sb = sb + "%(escape)%(c)"
}
}
var enc = sb.bytes.toList
var i = 0
for (c in enc) {
var k = key[i%4].bytes[0] - 48
if (k != 0) {
var j = c - 48
enc[i] = 48 + ((j + k) % 10)
}
i = i + 1
}
return enc.map { |b| String.fromByte(b) }.join()
}
 
var decrypt = Fn.new { |encoded|
var enc = encoded.bytes.toList
var i = 0
for (c in enc) {
var k = key[i%4].bytes[0] - 48
if (k != 0) {
var j = c - 48
enc[i] = 48 + ((j >= k) ? (j - k) % 10 : (10 + j - k) % 10)
}
i = i + 1
}
var len = enc.count
var sb = ""
i = 0
while (i < len) {
var c = enc[i]
var idx = rows.indexOf((c-48).toString)
if (idx == -1) {
var idx2 = c - 48
sb = sb + board[idx2]
i = i + 1
} else if ("%(c-48)%(enc[i + 1]-48)" == escape) {
sb = sb + (enc[i + 2] - 48).toString
i = i + 3
} else {
var idx2 = idx * 10 + enc[i + 1] - 48
sb = sb + board[idx2]
i = i + 2
}
}
return sb
}
 
var messages = [
"Attack at dawn",
"One night-it was on the twentieth of March, 1888-I was returning",
"In the winter 1965/we were hungry/just barely alive",
"you have put on 7.5 pounds since I saw you.",
"The checkerboard cake recipe specifies 3 large eggs and 2.25 cups of flour."
]
for (message in messages) {
var encrypted = encrypt.call(message)
var decrypted = decrypt.call(encrypted)
System.print("\nMessage : %(message)")
System.print("Encrypted : %(encrypted)")
System.print("Decrypted : %(decrypted)")
}</syntaxhighlight>
 
{{out}}
<pre>
Message : Attack at dawn
Encrypted : 3565257935743007
Decrypted : ATTACKATDAWN
 
Message : One night-it was on the twentieth of March, 1888-I was returning
Encrypted : 495786945533698149645468540384645875238925776668221480708005915367278976
Decrypted : ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
 
Message : In the winter 1965/we were hungry/just barely alive
Encrypted : 89645417896270736648201450026959060839767024608116557470618482160
Decrypted : INTHEWINTER1965WEWEREHUNGRYJUSTBARELYALIVE
 
Message : you have put on 7.5 pounds since I saw you.
Encrypted : 61983605685800834914704829124087264189730245691940889
Decrypted : YOUHAVEPUTON7.5POUNDSSINCEISAWYOU.
 
Message : The checkerboard cake recipe specifies 3 large eggs and 2.25 cups of flour.
Encrypted : 160225770664742408892673362274738052905225343251668487244454469139746678907466041088039436848815704
Decrypted : THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.
</pre>
 
=={{header|zkl}}==
{{trans|D}}
<langsyntaxhighlight lang="zkl">var [const]
val2key=Dictionary(
"A","30", "B","31", "C","32", "D","33", "E","5", "F","34", "G","35",
Line 1,695 ⟶ 2,900:
fcn encode(txt){ txt.toUpper().pump(String,val2key.find.fp1("")) }
fcn decode(str){ RegExp("79.|3.|7.|.").munchpump(str).pump(,String,key2val.get) }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">txt:="One night-it was on the twentieth of March, 1888-I was returning";
str:=encode(txt);
println("Encoded: ", str);
println("Decoded: ", decode(str));</langsyntaxhighlight>
{{out}}
<pre>
2,122

edits