Task

Implement functions to encrypt and decrypt a message using the 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.




with javascript_semantics
function read_table(string cb)
    sequence encode = repeat("",128),
             decode = repeat(0,128),
             row = {0}
    if length(cb)!=30 then crash("table wrong length") end if
    for i=1 to 30 do
        integer c = cb[i]
        if c=' ' then
            row &= i-1
        else
            integer code = row[floor((i-1)/10)+1]*10+mod((i-1),10)
            encode[c] = sprintf("%d",code)
            decode[code+1] = c
        end if
    end for
    return {encode, decode}
end function
 
function encipher(sequence encode, string s, bool strip=false)
    string res = ""
    for i=1 to length(s) do
        integer c = upper(s[i]), code
        if c>='0' and c<='9' then
            res &= encode['.']&c
        elsif c>='A' and c<='Z' then
            res &= encode[c]
        elsif not strip or c='/' then   -- (see note)
            res &= encode['/']
        end if
    end for
    return res
end function 
 
function decipher(sequence decode, string s, bool strip=false)
    string res = ""
    integer i = 1
    while i<=length(s) do
        integer c = s[i]-'0'+1
        if decode[c]=0 then
            i += 1
            c = (c-1)*10+s[i]-'0'+1
        end if
        integer d = decode[c]
        if d='.' then
            i += 1
            d = s[i]
        elsif d='/' and not strip then  -- (see note)
            d = ' '
        end if
        res &= d
        i += 1
    end while
    return res
end function
 
constant cb =  "ET AON RIS"&
               "BCDFGHJKLM"&
               "PQ/UVWXYZ."
sequence {encode,decode} = read_table(cb)
 
--  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.")
 
string msg = "In the winter 1965/we were hungry/just barely alive"
printf(1,"message: %s\n", {msg})
string enc = encipher(encode, msg),
       dec = decipher(decode, enc)
printf(1,"encoded: %s\n", {enc})
printf(1,"decoded: %s\n", {dec})
 
printf(1,"\nNo spaces:\n")
enc = encipher(encode, msg, true)
dec = decipher(decode, enc, true)
printf(1,"encoded: %s\n", {enc})
printf(1,"decoded: %s\n", {dec})
