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.




procedure main()
StraddlingCheckerBoard("setup","HOLMESRTABCDFGIJKNPQUVWXYZ./", 3,7)
 
text := "One night. it was on the twentieth of March, 1888. I was returning"
write("text   = ",image(text))
write("encode = ",image(en := StraddlingCheckerBoard("encode",text)))
write("decode = ",image(StraddlingCheckerBoard("decode",en)))
end
 
procedure StraddlingCheckerBoard(act,text,b1,b2)
static SCE,SCD
case act of {
   "setup" : {  
      if (b1 < b2 < 10) & (*text = *cset(text) = 28) then {
         SCE := table("")   
         SCD := table()         
         esc := text[-1]                               # escape
         every text[(b1|b2)+1+:0] := " "               # blanks
         uix := ["",b1,b2]                             # 1st position
         every c := text[1 + (i := 0 to *text-1)] do   # build translation
            if c ~== " " then                          # skip blanks
               SCD[SCE[c] := SCE[map(c)] := uix[i/10+1]||(i%10) ] := c         
         every c := !&digits do 
            SCD[SCE[c] := SCE[esc] || c] := c
         delete(SCD,SCE[esc])
         delete(SCE,esc)          
         }
         else stop("Improper setup: ",image(text),", ",b1,", ",b2)
      }
   "encode" : {
      every (s := "") ||:= x := SCE[c := !text]
      return s
      }
   "decode" : {  
      s := ""
      text ? until pos(0) do 
         s ||:= \SCD[k := move(1 to 3)]
      return s       
      }
   }
end