铁栏杆密码 - 寻找更好的解决方案

8
我已经用Python编写了栅栏密码。我想知道是否有更好的解决方案。
对于那些不知道什么是栅栏密码的人来说,它基本上是一种将明文以创建螺旋线性模式的方式进行编写的方法。例如,当使用密钥为3时,“FOOBARBAZ”进行栅栏加密的结果如下:
F . . . A . . . Z . . .
. O . B . R . A . Q . X
. . O . . . B . . . U .

将上述螺旋线逐行阅读,密文变为“FAZOBRAQXOBU”。更多信息请参见-栅栏密码 - 维基百科

def cipher(s, key, graph=False) :
    down=True
    raw_out=[]
    out=''
    i=0
    for x in range(key) :
        raw_out.append({})
    for pos in range(len(s)) :
        raw_out[i][pos]=s[pos]
        if i==key-1 :
            down=False
        if i==0 :
            down=True
        if down :
            i=i+1
        else :
            i=i-1
    for p in raw_out :
        for q in p :
            out+=p[q]
    if graph :
        return raw_out
    return out

def decipher(s, key) :
    map_list=cipher(s, key, True) #CREATING JUST FOR MAPPING - WHICHth CHARACTER OF THE STRING - IS WHICHth CHARACTER OF THE CIPHER
    new={}
    out=''
    s_counter=0
    for x in map_list :
        for y in x :
            new[y]=s[s_counter]
            s_counter+=1
    for p in new :
        out+=new[p]
    return map_list

我在想是否有更好的方法来完成这个任务,因为我的程序非常耗费资源,需要使用多个字典。

欢迎使用任何编程语言编写代码。

3个回答

13

就是为了好玩...

def fence(lst, numrails):
    fence = [[None] * len(lst) for n in range(numrails)]
    rails = range(numrails - 1) + range(numrails - 1, 0, -1)
    for n, x in enumerate(lst):
        fence[rails[n % len(rails)]][n] = x

    if 0: # debug
        for rail in fence:
            print ''.join('.' if c is None else str(c) for c in rail)

    return [c for rail in fence for c in rail if c is not None]

def encode(text, n):
    return ''.join(fence(text, n))

def decode(text, n):
    rng = range(len(text))
    pos = fence(rng, n)
    return ''.join(text[pos.index(n)] for n in rng)

z = encode('ATTACK.AT.DAWN', 3)    
print z # ACTWTAKA.ANT.D
y = decode(z, 3)
print y # ATTACK.AT.DAWN

返回 [c for rail in fence for c in rail if c is not None] - 哎呀,这就是我讨厌 Python 的原因。 - PintoDoido
1
这就是我喜欢Python的原因:return [c for rail in fence for c in rail if c is not None] - Vandit Shah
如果你理解它,那就很棒了...我打赌! - Vandit Shah

2

请在我的博客中查看解释。

(define (waves str h)
  (define (down str)
    (if (>= h (length str))
        (list (fill h str))
        (cons (take h str) (up (drop h str)))))
  (define (up str)
    (if (>= (- h 2) (length str))
        (list (pad (fill (- h 2) str)))
        (cons (pad (take (- h 2) str)) (down (drop (- h 2) str)))))
  (define (pad str) (append (list X) (reverse str) (list X)))
  (define (fill h str) (append str (make-list (- h (length str)) X)))
  (down str))

(define (fence lox h)
  (define a (apply append (transpose (waves lox h))))
  (filter (lambda (e) (not (eq? X e))) a))

(define (encipher str h)
  (list->string (fence (string->list str) h)))

(define (decipher str h)
  (define e (fence (range (string-length str)) h))
  (define x (map list e (string->list str)))
  (define y (sort (lambda (i j) (<= (car i) (car j))) x))
  (define z (map cadr y))
  (list->string z))

0

我最近在Python 3中实现了加密操作,我相信这个解决方案值得分享:

from itertools import chain, cycle


def rail_fence(plaintext: str, n: int) -> str:
    rows = [""] * n
    zigzag = cycle(chain(range(n - 1), range(n - 1, 0, -1)))
    for i, c in zip(zigzag, plaintext):
        rows[i] += c
    
    return "".join(rows)

例子:

>>> rail_fence("FOOBARBAZQUX", 3) 
'FAZOBRAQXOBU'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接