Background
One-hundred and thirteen years ago, amateur cryptographer Félix Delastelle published his work on the four-square cipher, a digraphic substitution cipher that accepts two permutations of a 25-letter alphabet as keys and encodes messages consisting of those letters.
Like most pen-and-paper ciphers, the four-square cipher does not have any cryptographic value today, but at the time of its invention, it had a significant advantage over its monographic counterparts.
One-hundred and thirteen years later, Alice Delastelle decides to improve the four-square cipher by increasing the alphabet's size and the number of keys.[citation needed]
Key setup
The alphabet contains the following characters (starting with space):
!"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
Given a pass phrase, we construct a permutation of this alphabet as follows:
Keep only the first occurrence of each character.
Append the unused characters from the alphabet, in their natural order.
After turning four pass phrases into four keys, we split each key into a square of side length 7 and arrange the four resulting squares so that they form one big square.
For example, if the pass phrases were
PROGRAMMING PUZZLES & CODE GOLF
POPULARITY CONTESTS & CODE BOWLING
CORRECT HORSE BATTERY STAPLE
DON'T TELL EVE!!!
the keys would be constructed and arranged like this:
PROGAMI POULARI
N UZLES TY CNES
&CDF!"# &DBWG!"
$%'()*+ #$%'()*
,-./:;< +,-./:;
=>?@BHJ <=>?@FH
KQTVWXY JKMQVXZ
CORET H DON'T E
SBAYPL! LV!"#$%
"#$%&'( &()*+,-
)*+,-./ ./:;<=>
:;<=>?@ ?@ABCFG
DFGIJKM HIJKMPQ
NQUVWXZ RSUWXYZ
Encryption
Given a plaintext message such as
ALICE LOVES BOB.
we append 0 or 1 spaces to make its length even and split it into character pairs:
["AL" "IC" "E " "LO" "VE" "S " "BO" "B."]
For each character pair, we locate the the first character in the first square (reading order) and the second in the fourth.
Then, we choose the characters in the remaining squares such that the four selected characters form a rectangle whose sides are parallel to the sides of the squares.
Finally, we replace the character pair by the selected characters of the second and third square.
For our example string, this yields
["PP" "A@" "E " "YT" "ZE" "EH" "=T" "<-"]
resulting in the following ciphertext:
PPA@E YTZEEH=T<-
Task
Write a program or function that accepts four pass phrases and a plaintext, uses the above variant of the four-square cipher to encrypt it and returns the resulting ciphertext.
Details:
The five input strings will consist solely of characters of the mentioned alphabet.
The five input strings can be read in any order, as such, a single string delimited by newlines or as an array of five strings.
You may assume that none of the strings is empty.
The output must be a single string.
If you choose to print the output to STDOUT, you may print only the characters of the ciphertext and (optionally) a trailing newline.
Standard code-golf rules apply.
Test cases
In all test cases, the first four strings correspond to the key squares in reading order and the last input string to the plaintext.
Input
PROGRAMMING PUZZLES & CODE GOLF
POPULARITY CONTESTS & CODE BOWLING
CORRECT HORSE BATTERY STAPLE
DON'T TELL EVE!!!
ALICE LOVES BOB.
Output
PPA@E YTZEEH=T<-
Input
!"#$%&'()*+,-./:;<=>
!"#$%&'()*+,-./:;<=>?@ABCDE
!"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKL
!"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRS
HELLO, WORLD!
Output
LALLR)#TROKE !
Input
,'K AB-Q=?@("W$>XM).C#<I:G!OLP*+;SZJTU%NED/&VFHRY
:,-D$C<SU=IYHFVA;! JG/M&L+WT%#.Q@(N*R")EZOBKX?'>P
L()JX,BND?Z<>P*FU%=O@&KIC+A!Y:;$SWHR.EMG'/T"QV #-
<->CI")AP Q:+U;O/F(KH&ER!MW?X'VJLZ#.,ドルBSGN@TD%*Y=
SPIN THE PPCG WHEEL OF BLAME!
Output
#>TE,VK+,ZQ(&<[email protected]@DM%NAC&>
Input
& %(,-#)$@?/=>'*"<:;!.+
=/$- ?;',@#!(&<")%.:>+*
&%-/<?.;$'#:=!( ,>"+*)@
=,<-*?#.'@/;>%!+:(& ")$
HNRA#JX$H %JAV+"GTS,
Output
GOOD LUCK, HAVE FUN.
3 Answers 3
Pyth, (削除) 74 (削除ここまで) 71 bytes
L+%eb7*7/hb7Jcms+oxdN{d--CMr33 91`MTd.z2ssm@VeJ,ydy_dCmxLhdedC,hJ.tcz2d
Could probably be optimized a lot. I use a lot of zipping.
Takes input in the following order:
ALICE LOVES BOB.
PROGRAMMING PUZZLES & CODE GOLF
DON'T TELL EVE!!!
POPULARITY CONTESTS & CODE BOWLING
CORRECT HORSE BATTERY STAPLE
CJam, (削除) 52 (削除ここまで) (削除) 50 (削除ここまで) (削除) 49 (削除ここまで) (削除) 47 (削除ここまで) (削除) 46 (削除ここまで) 44 bytes
l2/qN/'[,32>A,s-f|2/f{~@S+2<.#_7f%_W%.m.m.=}
The input order is lines 5, 2, 3, 1, 4. Try it online.
(-1 byte thanks to @MartinBüttner, -2 bytes thanks to @Dennis)
Explanation
l2/ Read the message and split into chunks of 2
qN/ Read rest of input and split by newlines (pass phrases)
'[,32> Generate " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
A,s- Remove digits 0123456789
f| Setwise OR with each pass phrase to remove duplicates, giving keys
2/ Split keys into two pairs
f{ ... } For each message chunk...
~ Unwrap key pairs
@S+2< Add a space to the message chunk then cap to length 2
.# Find the two chars in keys 1, 4
_7f% Copy indices and perform modulo 7 on both
_W% Copy and reverse
.m.m Vectorised subtraction twice
.= Apply both indices to keys 2, 3
For the indices, we want to swap the least significant digits, base 7. For instance, for the first example AL are indices 4 and 7 in keys 1 and 4 respectively. In base 7, this is [0 4] and [1 0]. Swapping the least significant digits gives [0 0] and [1 4], i.e. 0 and 11, and this corresponds to P and P in keys 2 and 3 respectively.
However, instead of base converting, the code does the following:
[4 7] A: Initial indices
[4 0] B: Indices mod 7
[0 4] C: Reverse of B
[4 -4] B-C
[0 11] A-(B-C)
Pyth - (削除) 88 (削除ここまで) (削除) 86 (削除ここまで) (削除) 83 (削除ここまで) (削除) 78 (削除ここまで) (削除) 76 (削除ここまで) (削除) 75 (削除ここまで) 72 bytes
8 bytes saved thanks to @orlp.
Waaay too long, I'm pretty unhappy with this, but just posting it while I look for a better way to handle the squares.
Jm+oxdN{d-+d-CMr33 91`MTd.zsms@VtPJ,+*7hKs.DR7xV,hJeJdeK+*7@[email protected]
-
\$\begingroup\$ You can replace
c+e.z*%le.z2d2withC.tce.z2d. Don't ask :) \$\endgroup\$orlp– orlp2015年08月01日 00:00:18 +00:00Commented Aug 1, 2015 at 0:00