MATL, 70 bajtów (ogółem)
f'(.{'iV'})(.{1,'2GqqV'})'5$h'$1'0'$2'0K$hYX2Get2LZ)P2LZ(!tg)i?&S]1Gw)
Wypróbuj w MATL Online.
Wypróbuj wiele przypadków testowych
Pobiera flagę jako trzecie wejście, F
aby zaszyfrować ciąg, T
odszyfrować go (dzięki Kevin Cruijssen za ten pomysł).
Zaczęło się to od odpowiedzi Julii, dopóki nie zdałem sobie sprawy, że ścisłe pisanie stało się zbyt duże, szczególnie do rozszyfrowania. Oto kod Julii, który miałem do szyfrowania (przeniesiony do wersji V0.6 dla 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)))[:]),"ø","")
Wypróbuj online!
Wyjaśnienie:
Operacja ogrodzenia szynowego
F . . . A . . . Z . . . .
O . B . R . A . Q . X
O . . . B . . . U
może być postrzegany jako odczyt r = 3 znaki wejściowe, następnie odczytanie znaków r-2 oraz przedrostek i przyrostek z wartościami pozornymi (wartości zerowe), a następnie ponowne odczytanie znaków r itp., za każdym razem tworząc nową kolumnę:
F.A.Z.
OBRAQX
O.B.U.
następnie odwracanie co drugą kolumnę (ponieważ zag zygzak idzie w górę zamiast w dół, co robi różnicę, gdy r> 3), następnie odczytywanie tej macierzy wzdłuż wierszy i usuwanie fałszywych znaków.
Odszyfrowanie nie wydawało się mieć takich oczywistych wzorców, ale kiedy szukałem tego, natknąłem się na ten post , który powiedział mi, że (a) był to dobrze znany i (być może?) Algorytm szyfrów szynowych oraz ( b) rozszyfrowanie było prostym ponownym użyciem tej samej metody, nadaniem mu wskaźników ciągu i uzyskaniem wskaźników tych wskaźników po zaszyfrowaniu i odczytaniu tekstu zaszyfrowanego w tych miejscach.
Ponieważ odszyfrowanie musi działać w oparciu o indeksy, kod ten szyfruje również przez sortowanie indeksów ciągu, a następnie w tym przypadku po prostu indeksuje te uporządkowane indeksy.
% 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