Encrypting a columnar transposition cipher

亡梦爱人 提交于 2020-02-24 12:00:08

问题


I'm trying to figure out how to encrypt a columnar transposition cipher in Python given a plaintext uppercase string and a number key of any length. For example, if the key is 3124 and the string is 'IHAVETWOCATS', it would organize the string like so:

3124
IHAV
ETWO
CATS

and then return the characters in column 1 first, then column 2, etc, until finally returning the encrypted string 'HTAAWTIECVOS'. So far I know that I'll need to use an accumulator, and I've been toying with the idea of using a dictionary, but I'm just completely stuck. These are some of the functions I've tried:

def columnar(plaintext,key):
    cipher=''
    acc=0
    for i in range(len(key)):
        while acc<(len(plaintext)/len(key)):
            cipher=cipher+plaintext[i+acc*5]
            acc=acc+1
    return(cipher)

^This only returns a few letters, not a string of appropriate length.

def columnar(plaintext,key) values={} seqlist=[] nextvalue=1 indices=rand(len(key)) for letter in plaintext: for i in indices: if letter==key[i]: values[i]=nextvalue nextvalue=nextvalue+1 for i in indices: seqlist.append(values[i]) return seqlist

^The above function returns a KeyError: 0 error. Thank you very much for any help!


回答1:


def split_len(seq, length):
    return [seq[i:i + length] for i in range(0, len(seq), length)]

def encode(key, plaintext):

    order = {
        int(val): num for num, val in enumerate(key)
    }

    ciphertext = ''
    for index in sorted(order.keys()):
        for part in split_len(plaintext, len(key)):
            try:
                ciphertext += part[order[index]]
            except IndexError:
                continue

    return ciphertext

print(encode('3214', 'IHAVETWOCATS'))
#>>> HTAAWTIECVOS

split_len is by Ian Bicking

So i split the code into chunks with split_len then use dictionary comprehension to just get correct order of indexes and finally i concatanate the letters in that order.




回答2:


def encode(txt,key):
    sz = len(key)  # how big are the columns 
    cols = list(map("".join,zip(*zip(*[iter(txt)]*sz)))) # list partitioned into columns
    return "".join([cols[key.index(str(c))] for c in range(1,sz+1)])



encoded = encode("IHAVETWOCATS","3124")
print encoded

is probably how I would do it



来源:https://stackoverflow.com/questions/24872411/encrypting-a-columnar-transposition-cipher

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!