NB. the playfair cipher with AlliedEnvy: http://codegolf.stackexchange.com/a/23320/5138 NB. 167 char including trailing newline at time of writing p=:4 :0 a=.u:65+9-.~i.26 ,_2(5|,:~@|.@(=/)+$$,A.~5*1-0{=/)&.(5 5#:(~.n x,a)&i.)\(,'X'#~2|#)(({.,'X',}.)~1+2*1{&I._2{.\2=/\]) ::]^:_(n=.a(e.~#])'JI'charsub toupper)y ) NB. usage is easy: 'KEY' p 'PLAINTEXT' 'Stack Overflow' p 'The cat crept into the crypt, crapped, and crept out again.' NB. SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY NB. explanation via explosion! a=.u:65+9-.~i.26 NB. the playfair alphabet: alphabet minus J i.26 NB. create a list of the numbers 0 through 25 9-.~ NB. remove the number 9 65+ NB. add 65 to everything a=.u: NB. convert ascii values to characters, assign to a (n=.a(e.~#])'JI'charsub toupper) NB. flatten to alphabet, filter j out toupper NB. convert any lowercase letters to uppercase 'JI'charsub NB. replace all J with I a NB. alphabet from before (e.~ ) NB. test to see whether each letter is in the alphabet #] NB. select those letters out of the string n=. NB. assign this function to n, we'll need it for later (({.,'X',}.)~1+2*1{&I._2{.\2=/\]) ::]^:_ NB. add in Xs between repeating letters in the same pair 2=/\] NB. between each pair of letters, test for equality _2{.\ NB. now between each non-overlapping pair, take the first element NB. this corresponds to equality over each non-overlapping pair, NB. but correctly handles the case when the string length is odd &I. NB. convert the list of booleans to a list of indices where it was true 1{ NB. select the first item, if it exists; throws error if empty list ::] NB. catch this error if it occurs, returning the original string 1+2* NB. index * 2 + 1 ({.,'X',}.)~ NB. insert an X after the first 1+2*idx characters ^:_ NB. repeat until no resulting change, i.e. until we catch the error NB. that appears when there's nothing to break up (,'X'#~2|#) NB. append an X if there are an odd number of characters 2|# NB. take the length of the string, mod 2 'X'#~ NB. take that many (0 or 1) copies of X , NB. append it to the string ,_2(...)&.(5 5#:(~.n x,a)&i.)\ NB. actually performing the playfair encoding ( n x,a) NB. append the playfair alphabet to the end of the key, then apply n from before ~. NB. take only the unique characters, in order &i. NB. find the index of each letter from the string in this keytable 5 5#: NB. expand this base 5 into a pair of coordinates, row and column (...)&.( ) NB. perform this transformation, then (...), then the INVERSE transformation NB. i.e. convert chars to indices, do (...), then back to chars _2 \ NB. perform the above on 2-char non-overlapping pairs , NB. run all of it back into a single-line string (5|,:~@|.@(=/)+$$,A.~5*1-0{=/) NB. playfair the indices =/ NB. test whether the rows and/or the columns are equal 0{ NB. take the result for rows 5*1- NB. do some math, making 0 if true, 5 if false , NB. run the indices into a line A.~ NB. permute the list of indices by the number at right: NB. 0 makes no change, and 5 swaps the columns $$ NB. restore the original shape of the indices |.@(=/) NB. row/column equality test, but this time reverse the pair ,:~@ NB. laminate this result with itself, so that we have NB. 0 1 1 0 NB. 0 1 if rows equal, or 1 0 if columns equal, NB. or all zeroes otherwise 5| + NB. add the two results together and take everything mod 5 NB. tada! this is the encryption half of the playfair cipher NB. as a bonus, we can also make a parallel decryption predicate which operates inalmost the exact same way: NB. it would subtract the shifts made for matching rows/columns, and then strip out all the Xs in the result NB. that are at the end or in between identical letters pi=:4 :0 :.p NB. playfair inverse (}.~'X'-@={:)(#~1-'X'&=*0,@,.0,~2=/\_2{.\]),_2(5|,:~@|.@(=/)-~$$,A.~5*1-0{=/)&.(5 5#:(~.(n=.a(e.~#])'JI'charsub toupper)x,a=.u:65+9-.~i.26)&i.)\(,'X'#~2|#)y ) p=:p f. :.pi NB. :. is used to define inverses for J; f. is used to dereference p for the definition 'Stack Overflow' pi 'SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY' NB. THECATCREPTINTOTHECRYPTCRAPPEDANDCREPTOUTAGAIN