Rebol3 Code Examplex
Straddling checkerboard
Encode or decode text with a straddling checkerboard cipher.
Rebol [
title: "Rosetta code: Straddling checkerboard"
file: %Straddling_checkerboard.r3
url: https://rosettacode.org/wiki/Straddling_checkerboard
]
register-codec [
name: 'straddle
type: 'cryptography
title: "Straddling checkerboard"
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"]
[#"7" #"P" #"Q" #"U" #"V" #"W" #"X" #"Y" #"Z" #"." #"/"]
]
header: T/1 ;; digit labels for each column
singles: T/2 ;; single-digit letters (H O L M E S R T)
row3: T/3 ;; two-digit letters starting with 3
row4: T/4 ;; two-digit letters starting with 7
encode: function [
{Encode plaintext using the straddling checkerboard.
Single-digit letters (row 2) encode to one digit;
all others encode to two digits (row prefix + column digit).}
plaintext [string!]
][
result: copy ""
foreach ch plaintext [
foreach row (next T) [ ;; skip header row
if col: index? find row ch [
repend result [row/1 header/:col] ;; row prefix ("" for singles) + column digit
break
]
]
]
result
]
decode: function [
{Decode a straddling checkerboard ciphertext back to plaintext.
Reads one digit at a time; if it matches a row prefix (3 or 7)
the next digit selects the column in that row.}
ciphertext [string!]
][
result: copy ""
pos: 1
while [pos <= length? ciphertext] [
digit: ciphertext/(++ pos)
append result case [
digit == row3/1 [ ;; escape digit 3 -> read next for row3
digit: ciphertext/(++ pos)
letter: row3/(2 + digit - #"0")
if letter == #"/" [++ pos]
letter
]
digit == row4/1 [ ;; escape digit 7 -> read next for row4
digit: ciphertext/(++ pos)
row4/(2 + digit - #"0")
]
true [ ;; single-digit: look up in singles row
singles/(2 + digit - #"0")
]
]
]
result
]
]
plaintext: "One night-it was on the twentieth of March, 1888-I was returning"
encoded: encode 'straddle plaintext
decoded: decode 'straddle encoded
print rejoin ["Original: " plaintext]
print rejoin ["Encoded: " encoded]
print rejoin ["Decoded: " decoded]