MATL, 70 bytes (total)
f'(.{'iV'})(.{1,'2GqqV'})'5$h'$1'0'$2'0K$hYX2Get2LZ)P2LZ(!tg)i?&S]1Gw)
Experimente no MATL Online
Experimente vários casos de teste
Toma uma bandeira como terceira entrada, F
para codificar a string, T
decifrá-la (obrigado a Kevin Cruijssen por essa ideia).
Isso começou como uma resposta de Julia até que eu percebi que a digitação estrita atrapalhava demais, especialmente para decifração. Aqui está o código Julia que eu tinha para codificação (com suporte para v0.6 para 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)))[:]),"ø","")
Experimente online!
Explicação:
A operação da cerca do trilho
F . . . A . . . Z . . . .
O . B . R . A . Q . X
O . . . B . . . U
pode ser visto como lendo r = 3 caracteres de entrada, depois lendo r-2 e prefixando e sufixando valores dummy (nulos), depois lendo r caracteres novamente etc., criando uma nova coluna sempre:
F.A.Z.
OBRAQX
O.B.U.
depois, inverta cada segunda coluna (já que a parte zag do ziguezague sobe em vez de para baixo, o que faz diferença quando r> 3), depois lê essa matriz ao longo das linhas e remove os caracteres fictícios.
A decifração não parecia ter padrões óbvios como esse, mas, ao pesquisar sobre isso, me deparei com este post , que me dizia que (a) esse era um algoritmo bem conhecido e (possivelmente?) Publicado para cifras ferroviárias e ( b) decifração era uma simples reutilização do mesmo método, fornecendo os índices da string e obtendo os índices desses índices após a codificação, e lendo o texto cifrado nesses locais.
Como a decifração precisa fazer as coisas trabalhando em índices, esse código também codifica, classificando os índices da string e, nesse caso, apenas indexando esses índices reorganizados.
% 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