(phixonline)--> with javascript_semantics constant keyword = "Playfair example", option = 'Q' -- ignore Q -- option = 'J' -- replace J with I sequence table, findchar procedure build_table() table = repeat(repeat(' ',5),5) findchar = repeat(0,26) findchar[option-'A'+1] = {0,0} -- (note any (J/Q) in keyword are simply ignored) string alphabet = upper(keyword) & tagset('Z','A') integer i=1, j=1 for k=1 to length(alphabet) do integer c = alphabet[k] if c>='A' and c<='Z' then integer d = c-'A'+1 if findchar[d]=0 then table[i][j] = c findchar[d] = {i,j} j += 1 if j=6 then i += 1 if i=6 then exit end if -- table filled j = 1 end if end if end if end for end procedure build_table() function clean_text(string plaintext) -- -- get rid of any non-letters and insert X between duplicate letters -- plaintext = upper(plaintext) string cleantext = "" integer prevChar = -1 for i=1 to length(plaintext) do integer nextChar = plaintext[i] if nextChar>='A' and nextChar<='Z' and (nextChar!='Q' or option!='Q') then if nextChar='J' and option='J' then nextChar = 'I' end if if nextChar=prevChar then cleantext &= 'X' end if cleantext &= nextChar prevChar = nextChar end if end for if odd(length(cleantext)) then -- dangling letter at end so add another letter to complete digraph cleantext &= iff(cleantext[$]='X'?'Z':'X') end if return cleantext end function function remove_x(string text) for i=2 to length(text)-1 do if text[i]='X' and ((text[i-1]=' ' and text[i-2]=text[i+1]) or (text[i+1]=' ' and text[i-1]=text[i+2])) then text[i] = '_' end if end for return text end function function playfair(string text, integer step, sequence d) -- -- text may be the plaintext or the encoded version -- step is 2 for plaintext, 3 for encoded(/skip spaces) -- d is {2,3,4,5,1} instead of mod(+1,5), or -- {5,1,2,3,4} -- -1 -- string res = "" for i=1 to length(text) by step do integer {row1, col1} = findchar[text[i]-'A'+1], {row2, col2} = findchar[text[i+1]-'A'+1] if i>1 then res &= " " end if if row1=row2 then {col1,col2} = {d[col1],d[col2]} elsif col1=col2 then {row1,row2} = {d[row1],d[row2]} else {col1,col2} = {col2,col1} end if res &= table[row1][col1] & table[row2][col2] end for return res end function function encode(string plaintext) return playfair(clean_text(plaintext),2,{2,3,4,5,1}) end function function decode(string ciphertext) -- ciphertext includes spaces we need to skip, hence by 3 return remove_x(playfair(ciphertext,3,{5,1,2,3,4})) end function printf(1,"Playfair keyword : %s\n",{keyword}) printf(1,"Option: J=I or no Q (J/Q) : %s\n",option) printf(1,"The table to be used is :\n\n%s\n\n",{join(table,"\n")}) string plaintext = "Hide the gold...in the TREESTUMP!!!!", encoded = encode(plaintext), decoded = decode(encoded) printf(1,"The plain text : %s\n\n",{plaintext}) printf(1,"Encoded text is : %s\n",{encoded}) printf(1,"Decoded text is : %s\n",{decoded})