ClearAll[MakeTranslationTable, PlayfairCipher, PlayfairDecipher] MakeTranslationTable[tt_List] := Module[{poss, in, out}, poss = Tuples[Tuples[Range[5], 2], 2]; Table[ If[p[[1, 1]] == p[[2, 1]], (* same row *) {in, out} = {p, {{p[[1, 1]], Mod[p[[1, 2]] + 1, 5, 1]}, {p[[2, 1]], Mod[p[[2, 2]] + 1, 5, 1]}}}; , If[p[[1, 2]] == p[[2, 2]], (* same column *) {in, out} = {p, {{Mod[p[[1, 1]] + 1, 5, 1], p[[1, 2]]}, {Mod[p[[2, 1]] + 1, 5, 1], p[[2, 2]]}}}; , (*rectangle*) {in, out} = {p, {{p[[1, 1]], p[[2, 2]]}, {p[[2, 1]], p[[1, 2]]}}}; ] ]; StringJoin[Extract[tt, in]] -> StringJoin[Extract[tt, out]] , {p, poss} ] ] PlayfairCipher[txt_String, key_String, iisj_ : True] := Module[{text, tt}, text = RemoveDiacritics[ToUpperCase[txt]]; tt = RemoveDiacritics[ToUpperCase[key]] <> CharacterRange["A", "Z"]; text //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""]; tt //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""]; If[iisj, tt //= StringReplace["J" -> "I"]; text //= StringReplace["J" -> "I"]; , tt //= StringReplace["Q" -> ""]; text //= StringReplace["Q" -> ""]; ]; tt //= Characters /* DeleteDuplicates; text = FixedPoint[StringReplace[#, x_ ~~ x_ :> x ~~ "X" ~~ x, 1] &, text]; If[OddQ[StringLength[text]], text = text <> "X"]; If[Length[tt] == 25, tt = Partition[tt, 5]; tt = MakeTranslationTable[tt]; text = StringPartition[text, 2]; StringRiffle[text /. tt, " "] , Print["Something went wrong!"] ] ] PlayfairDecipher[txt_String, key_String, iisj_ : True] := Module[{text, tt}, text = RemoveDiacritics[ToUpperCase[txt]]; tt = RemoveDiacritics[ToUpperCase[key]] <> CharacterRange["A", "Z"]; text //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""]; tt //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""]; If[iisj, tt //= StringReplace["J" -> "I"]; text //= StringReplace["J" -> "I"]; , tt //= StringReplace["Q" -> ""]; text //= StringReplace["Q" -> ""]; ]; tt //= Characters /* DeleteDuplicates; If[OddQ[StringLength[text]], text = text <> "X"]; If[Length[tt] == 25, tt = Partition[tt, 5]; tt = MakeTranslationTable[tt]; text = StringPartition[text, 2]; StringRiffle[text /. (Reverse /@ tt), " "] , Print["Something went wrong!"] ] ] PlayfairCipher["Hide the gold in...the TREESTUMP!!!", "Playfair example"] PlayfairDecipher[%, "Playfair example"]