# 围栏密码

10

-一个程序，读取一个字符串和一个密钥，并使用该密钥将该字符串编码为栅栏密码。-同样，编写一个用于反向功能的程序：使用钥匙解密铁栅栏。

``````F . . . A . . . Z . . . .
O . B . R . A . Q . X
O . . . B . . . U
``````

2

Paul R

9

## Python 133字节

``````def cipher(t,r):
m=r*2-2;o='';j=o.join
for i in range(r):s=t[i::m];o+=i%~-r and j(map(j,zip(s,list(t[m-i::m])+[''])))or s
return o
``````

``````>>> print cipher('FOOBARBAZQUX', 3)
FAZOBRAQXOBU

>>> print cipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 4)
AGMSYBFHLNRTXZCEIKOQUWDJPV

>>> print cipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 5)
AIQYBHJPRXZCGKOSWDFLNTVEMU

>>> print cipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 6)
AKUBJLTVCIMSWDHNRXEGOQYFPZ
``````

``````A         K         U
B       J L       T V
C     I   M     S   W
D   H     N   R     X
E G       O Q       Y
F         P         Z
``````

``````def cipher(text, rails):
m = (rails - 1) * 2
out = ''
for i in range(rails):
if i % (rails - 1) == 0:
# outer rail
out += text[i::m]
else:
# inner rail
char_pairs = zip(text[i::m], list(text[m-i::m]) + [''])
out += ''.join(map(''.join, char_pairs))
return out
``````

ShuklaSannidhya 2014年

@ShuklaSannidhya那你为什么接受一个不完整的答案？
Jo King

3
@JoKing为清楚起见，我发布解决方案的一年后添加了“两个程序”的要求。
primo

2

## APL 52 41

``````i←⍞⋄n←⍎⍞⋄(,((⍴i)⍴(⌽⍳n),1↓¯1↓⍳n)⊖(n,⍴i)⍴(n×⍴i)↑i)~' '
``````

``````FOOBARBAZQUX
3
FAZOBRAQXOBU

ABCDEFGHIJKLMNOPQRSTUVWXYZ
4
AGMSYBFHLNRTXZCEIKOQUWDJPV

ABCDEFGHIJKLMNOPQRSTUVWXYZ
5
AIQYBHJPRXZCGKOSWDFLNTVEMU

ABCDEFGHIJKLMNOPQRSTUVWXYZ
6
AKUBJLTVCIMSWDHNRXEGOQYFPZ
``````

``````i[⍋+\1,(y-1)⍴((n←⍎⍞)-1)/1 ¯1×1 ¯1+y←⍴i←⍞]
``````

ShuklaSannidhya 2014年

1

# Python 2，124 + 179 = 303字节

``````lambda t,k:''.join(t[i+j]for r in R(k)for i in R(k-1,len(t)+k,2*k-2)for j in[r-k+1,k+~r][:1+(k-1>r>0)]if i+j<len(t))
R=range``````

``````lambda t,k:''.join(t[dict((b,a)for a,b in enumerate(i+j for r in R(k)for i in R(k-1,len(t)+k,2*k-2)for j in[r-k+1,k+~r][:1+(k-1>r>0)]if i+j<len(t)))[m]]for m in R(len(t)))
R=range``````

Jo King

@乔金：我迟来了一个解密器。
Chas Brown

0

# MATL，总共70个字节

``````f'(.{'iV'})(.{1,'2GqqV'})'5\$h'\$1'0'\$2'0K\$hYX2Get2LZ)P2LZ(!tg)i?&S]1Gw)
``````

### 朱莉娅 0.6，191字节

``````!M=(M[2:2:end,:]=flipdim(M[2:2:end,:],2);M)

### 说明：

``````F . . . A . . . Z . . . .
O . B . R . A . Q . X
O . . . B . . . U``````

``````F.A.Z.
OBRAQX
O.B.U.``````

``````              % 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``````

0
``````int r=depth,len=plainText.length();
int c=len/depth;
char mat[][]=new char[r][c];
int k=0;
String cipherText="";
for(int i=0;i< c;i++)
{
for(int j=0;j< r;j++)
{
if(k!=len)
mat[j][i]=plainText.charAt(k++);
else
mat[j][i]='X';
}
}
for(int i=0;i< r;i++)
{
for(int j=0;j< c;j++)
{
cipherText+=mat[i][j];
}
}
return cipherText;
}
``````

Jo King

Οurous

0

# Java的10，459个451 445 439 327字节

``(s,k,M)->{int l=s.length,i=-1,f=0,r=0,c=0;var a=new char[k][l];for(;++i<l;a[r][c++]=M?s[i]:1,r+=f>0?1:-1)f=r<1?M?f^1:1:r>k-2?M?f^1:0:f;for(c=i=0;i<k*l;i++)if(a[i/l][i%l]>0)if(M)System.out.print(a[i/l][i%l]);else a[i/l][i%l]=s[c++];if(!M)for(r=c=i=0;i++<l;f=r<1?1:r>k-2?0:f,r+=f>0?1:-1)if(a[r][c]>1)System.out.print(a[r][c++]);}``

-12个字节感谢@ceilingcat
-112字节，将两个功能与一个附加的模式标志组合在一起作为输入。

### 说明：

``````(s,k,M)->{              // Method with character-array, integer, and boolean parameters
// and no return-type
int l=s.length,       //  Length of the input char-array
i=-1,             //  Index-integer, starting at -1
f=0,              //  Flag-integer, starting at 0
r=0,c=0;          //  Row and column integers, starting both at 0
var a=new char[k][l]; //  Create a character-matrix of size `k` by `l`
for(;++i<l            //  Loop `i` in the range (-1, `l`):
;                 //    After every iteration:
a[r][c++]=       //     Set the matrix-cell at `r,c` to:
M?s[i++]       //      If we're enciphering: set it to the current character
:1,            //      If we're deciphering: set it to 1 instead
r+=f>0?          //     If the flag is 1:
1            //      Go one row down
:             //     Else (flag is 0):
-1)          //      Go one row up
f=r<1?              //   If we're at the first row:
M?f^1            //    If we're enciphering: toggle the flag (0→1; 1→0)
:1               //    If we're deciphering: set the flag to 1
:r>k-2?           //   Else-if we're at the last row:
M?f^1            //    If we're enciphering: toggle the flag (0→1; 1→0)
:0               //    If we're deciphering: set the flag to 0
:                 //   Else (neither first nor last row):
f;               //    Leave the flag unchanged regardless of the mode
for(c=i=0;            //  Reset `c` to 0
i<k*l;i++)  //  Loop `i` in the range [0, `k*l`):
if(a[i/l][i%l]>0)   //   If the current matrix-cell is filled with a character:
if(M)             //    If we're enciphering:
System.out.print(a[i/l][i%l]);}
//     Print this character
else              //    Else (we're deciphering):
a[r][i]=s[c++]; //     Fill this cell with the current character
if(!M)                //  If we're deciphering:
for(r=c=i=0;        //   Reset `r` and `c` both to 0
i++<l           //   Loop `i` in the range [0, `l`)
;               //     After every iteration:
f=r<1?         //      If we are at the first row:
1           //       Set the flag to 1
:r>k-2?      //      Else-if we are at the last row:
0           //       Set the flag to 0
:            //      Else:
f,          //       Leave the flag the same
r+=f>0?        //      If the flag is now 1:
1          //       Go one row up
:           //      Else (flag is 0):
-1)        //       Go one row down
if(a[r][c]>1)     //    If the current matrix-cell is filled with a character:
System.out.print(a[r][c++]);}
//     Print this character``````