/* NetRexx */ options replace format comments java crossref symbols nobinary -- input arguments: -- encipher/decipher IQ-switch key text -- encipher/decipher - -- a character E, D (default E; . is an alias for E) -- IQ-switch - -- a character I, Q (default I for I==J, Q for exclude Q; . is an alias for I) -- key - -- the cipher key - default plugh_xyzzy (really just PLUGHXYZ) -- text - -- the text to encipher/decipher runSample(arg) return -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method cipher(d_, km, digraphs) public static if d_.upper() = 'D' then d_ = -1 -- encode or decode adjustment else d_ = +1 cipherText = '' loop dw = 1 to digraphs.words() -- process the digraphs one at a time digraph = digraphs.word(dw) cl = '' cr = '' -- get each letter from the digraph parse digraph dl +1 dr loop r_ = 1 to km[0] while (cl cr).words() < 4 -- locate the row/col of each letter in the cipher matrix clx = km[r_].wordpos(dl) crx = km[r_].wordpos(dr) if clx > 0 then cl = r_ clx if crx > 0 then cr = r_ crx end r_ -- process the digraph's rows, columns or rectangles select when cl.word(1) = cr.word(1) then do -- a row rx = cl.word(1) clx = cl.word(2) + d_ crx = cr.word(2) + d_ if clx > 5 then clx = 1 -- wrap if crx > 5 then crx = 1 if clx < 1 then clx = 5 if crx < 1 then crx = 5 cy = km[rx].word(clx) || km[rx].word(crx) cipherText = cipherText cy end when cl.word(2) = cr.word(2) then do -- a column cx = cl.word(2) rlx = cl.word(1) + d_ rrx = cr.word(1) + d_ if rlx > 5 then rlx = 1 -- wrap if rrx > 5 then rrx = 1 if rlx < 1 then rlx = 5 if rrx < 1 then rrx = 5 cy = km[rlx].word(cx) || km[rrx].word(cx) cipherText = cipherText cy end otherwise do -- a rectangle r1 = cl.word(1) r2 = cr.word(1) cy = km[r1].word(cr.word(2)) || km[r2].word(cl.word(2)) cipherText = cipherText cy end end end dw return cipherText.strip() -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method encipher(km, digraphs) public static return cipher('E', km, digraphs) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method decipher(km, digraphs) public static return cipher('D', km, digraphs) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getDigraphs(text, IorQ, ED) private static a2z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if ED.upper() \= 'D' then eks = 'X' else eks = '' tp = text.upper().translate('', a2z) text = text.upper().translate(' '.copies(tp.length()), tp).space(0) rtext = '' ll = '' loop while text \= '' parse text lc +1 text if ll \= lc then rtext = rtext || lc else rtext = rtext || eks || lc ll = lc end -- I == J or remove Q fixup if IorQ \= 'Q' then parse 'J I' IorQ sc . else sc = '' rtext = rtext.changestr(IorQ, sc) if rtext.length() // 2 \= 0 then rtext = rtext || eks digraphs = '' loop while rtext \= '' parse rtext digraph +2 rtext digraphs = digraphs digraph end return digraphs.space() -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getKey(key, IorQ) private static a2z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' kp = (key || a2z).upper() kr = '' loop while kp \= '' parse kp xx +1 kp if \xx.datatype('u') then iterate kr = kr xx kp = kp.changestr(xx, '') end if IorQ = 'I' | IorQ = 'J' | IorQ = '' then kr = kr.changestr('J', '') else kr = kr.changestr('Q', '') return kr.space() -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getKeyMatrix(kr) private static km = '' loop r_ = 1 while kr \= '' parse kr kp +10 kr km[0] = r_ km[r_] = kp end r_ return km -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method runSample(arg) private static parse arg ciph IorQ key text if ciph = '' | ciph = '.' then ciph = 'E' if IorQ = '' | IorQ = '.' then IorQ = 'I' if key = '' | key = '.' then key = 'plugh_xyzzy' if text = '' | text = '.' then text = 'NetRexx; not just a programing language for kings & queens!' kr = getKey(key.space(0), IorQ) km = getKeyMatrix(kr) digraphs = getDigraphs(text, IorQ, ciph) -- fixup for a Q in the text when Q is excluded (substitute K for Q) if IorQ.upper = 'Q' then digraphs = digraphs.changestr('Q', 'K') if ciph = 'E' then say text say digraphs if ciph.upper() = 'E' then say encipher(km, digraphs) else say decipher(km, digraphs) return