仿铁栅密码- 寻找更好的解决方案
我在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 个回答
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'
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))
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