MATL, 70 байт (всего)
f'(.{'iV'})(.{1,'2GqqV'})'5$h'$1'0'$2'0K$hYX2Get2LZ)P2LZ(!tg)i?&S]1Gw)
Попробуй на MATL Online
Попробуй несколько тестов
Принимает флаг как третий вход, F
чтобы зашифровать строку, T
чтобы расшифровать ее (спасибо Кевину Круйссену за эту идею).
Это началось с ответа Джулии, пока я не понял, что строгая типизация слишком мешает, особенно для расшифровки. Вот код Джулии, который у меня был для шифрования (перенесен в v0.6 для TIO):
!M=(M[2:2:end,:]=flipdim(M[2:2:end,:],2);M)
s|n=replace(String((!permutedims(reshape([rpad(replace(s,Regex("(.{$n})(.{1,$(n-2)})"),s"\1ø\2ø"),length(s)*n,'ø')...],n,:),(2,1)))[:]),"ø","")
Попробуйте онлайн!
Объяснение:
Железнодорожный забор
F . . . A . . . Z . . . .
O . B . R . A . Q . X
O . . . B . . . U
можно увидеть как чтение r = 3 символов ввода, затем чтение r-2 символов, добавление префикса и суффикса к пустым значениям (нулям), затем повторное чтение r символов и т. д., каждый раз создавая новый столбец:
F.A.Z.
OBRAQX
O.B.U.
затем реверсирует каждый второй столбец (поскольку зигзагообразная часть загона идет вверх, а не вниз, что имеет значение при r> 3), затем читает эту матрицу вдоль строк и удаляет фиктивные символы.
Дешифровка, похоже, не имела явных закономерностей, подобных этой, но при поиске по этому поводу я наткнулся на этот пост , в котором говорилось, что (а) это был хорошо известный и (возможно?) Опубликованный алгоритм для железнодорожных шифров, и ( б) дешифрование было простым повторным использованием того же метода, давая ему индексы строки и получая индексы этих индексов после шифрования, и читая зашифрованный текст в этих местах.
Поскольку дешифрование должно действовать, работая с индексами, этот код выполняет шифрование также путем сортировки индексов строки, а затем в этом случае просто индексации по этим переупорядоченным индексам.
% implicit first input, say 'FOOBARBAZQUX'
f % indices of input string (i.e. range 1 to length(input)
'(.{'iV'})(.{1,'2GqqV'})'5$h
% Take implicit second input, say r = 3
% Create regular expression '(.{$r})(.{1,$(r-2)})'
% matches r characters, then 1 to r-2 characters
% (to allow for < r-2 characters at end of string)
'$1'0'$2'0K$h % Create replacement expression, '$1\0$2\0'
YX % Do the regex replacement
2Ge % reshape the result to have r rows (padding 0s if necessary)
t2LZ) % extract out the even columns of that
P % flip them upside down
2LZ( % assign them back into the matrix
! % transpose
tg) % index into the non-zero places (i.e. remove dummy 0s)
i? % read third input, check if it's true or false
&S] % if it's true, decipherment needed, so get the indices of the
% rearranged indices
1Gw) % index the input string at those positions