0

復号化機能を機能させる方法を見つけようとして、多くの問題を抱えています。メッセージが3で割り切れる理想的なケースでは機能しますが、その後は完全に失われます。これを2つのレールで動作させることができたので、何をしなければならないかについて漠然とした考えがありますが、3つのレールではより多くの可能性があります. 私はかなり迷っています:(また、これらの印刷ステートメントはすべて、何が起こっているのかを理解するのを助けるためのものです.

import sys

def main():
    plaintext="abcdefgh"
    print(threeRailEncrypt(plaintext))
    print(threeRailDecrypt(threeRailEncrypt(plaintext)))


def threeRailEncrypt(plaintext):
    ciphertext=""
    rail1=""
    rail2=""
    rail3=""

    for i in range(len(plaintext)):
        if i%3 == 0:
            rail1=rail1+plaintext[i]
        elif i%3 == 1:
            rail2=rail2+plaintext[i]
        else:
            rail3=rail3+plaintext[i]

    ciphertext=rail1+rail2+rail3

    return(ciphertext)

def threeRailDecrypt(msg):
    if len(msg)%3==0:
        third=len(msg)//3
        print(third)
        rail1=msg[:third]
        rail2=msg[third:third*2]
        rail3=msg[third*2:]
        print(rail1,rail2,rail3)
        dm=""
        for i in range(third):
            dm=dm+rail1[i]
            dm=dm+rail2[i]
            dm=dm+rail3[i]
    else:
        third=(len(msg)//3)+1
        print(third)
        rail1=msg[:third]
        rail2=msg[third:third*2]
        rail3=msg[third*2:]
        print(rail1,rail2,rail3)
        dm=""
        for i in range(third):
            dm=dm+rail1[i]
            print(dm)
            dm=dm+rail2[i]
            print(dm)
            dm=dm+rail3[i]
            print(dm)
            if  len(rail2)>len(rail3):
                dm=dm+rail2[-1]
        return(dm)
main()
4

1 に答える 1

2

ストライドを使用して文字列 (またはその他のシーケンス) をスライスできます。それを使用して3文字ごとに選択できます:

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

傾向を逆転させるには、暗号文を 3 つのチャンクにスライスし、それらを使用itertools.zip_longest()して再度結合します。

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='')))

デモ:

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

ない最後の部分は次のzip_longestようになります。

# 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)
于 2013-10-03T00:01:29.207 に答える