Three Rail Decrypt when rails are different lengths

后端 未结 1 665
余生分开走
余生分开走 2021-01-26 06:25

Im having a ton of trouble trying to figure out how to get my decrypt function to work. It works in ideal cases where the msg is divisible by 3, but after that i am totally lost

相关标签:
1条回答
  • 2021-01-26 06:30

    You can slice strings (or any other sequence) using a stride; you can select every 3rd character with that:

    def threeRailEncrypt(plaintext):
        return plaintext[::3] + plaintext[1::3] + plaintext[2::3]
    

    To reverse the trend, slice up the ciphertext into three chunks and use itertools.zip_longest() to recombine them again:

    from itertools import zip_longest, chain
    
    def threeRailDecrypt(ciphertext):
        stride, remainder = divmod(len(ciphertext), 3)
        # how large was each of the three sections?
        sizes = [stride] * 3
        for i in range(remainder):
            sizes[i] += 1
        # slice ciphertext up into 3 sections again
        pos = 0
        pieces = []
        for s in sizes:
            pieces.append(ciphertext[pos:pos + s])
            pos += s
        # recombine the triplets
        return ''.join(chain.from_iterable(zip_longest(*pieces, fillvalue='')))
    

    Demo:

    >>> threeRailEncrypt('Foo bar baz and all')
    'F raa lob znaoab dl'
    >>> threeRailDecrypt(threeRailEncrypt('Foo bar baz and all'))
    'Foo bar baz and all'
    

    The last part without zip_longest would be:

    # recombine the triplets
    plaintext = []
    for i in range(len(parts[0])):
        for part in parts:
            try:
                plaintext.append(part[i])
            except IndexError:  # part too short
                pass
    return ''.join(plaintext)
    
    0 讨论(0)
提交回复
热议问题