【问题标题】:Trying to decrypt and print out a text file I encrypted in same program尝试解密并打印出我在同一程序中加密的文本文件
【发布时间】:2020-07-17 01:11:54
【问题描述】:

所以我终于想出了如何读取和加密文本文件。现在我必须创建第二个程序来打开加密文件,然后在屏幕上显示其解密内容。我很好,直到我不得不反转并弄清楚如何打印出字典中的键。任何帮助都很棒,TIA!

这是我的代码:

    dictionary = {'A':'D', 'B':'E', 'C':'F', 'D':'G', 'E':'H', 
            'F':'I', 'G':'J', 'H':'K','I':'L',\
            'J':'M', 'K':'N', 'L':'O', 'M':'P', 'N':'Q', 'O':'R', 
            'P':'S', 'Q':'T', 'R':'U',\
            'V':'Y', 'W':'Z', 'X':'A', 'Y':'B', 'Z':'C'}
    def encrypt_file():
        file = open('texttoencrypt.txt', 'r')
        new_file = open('encrypted_text.txt', 'w')

        while True:
            char = file.read(1)
             if not char:
                break
            char = char.upper()
            if char in dictionary.keys():
                 new_char = dictionary[char]
                 new_file.write(new_char)
            else:
                 new_file.write(char)

         file.close()
         new_file.close()

    encrypt_file()

    def decrypt_file():
        encrypted = open('encrypted_text.txt', 'r')
        decrypt = ''
        while True:
            char = encrypted.read(1)
            if not char:
                break
            for key, values in dictionary.items():
                 if char in values:
                     decrypt+= key
                 else:
                     decrypt += char
         print(decrypt)
         encrypted.close()

【问题讨论】:

    标签: python python-3.x dictionary encryption key-value


    【解决方案1】:

    请注意,您当前使用的词典是可逆的。因为字母“S”、“T”和“U”不存在,它们将被隐式映射到它们自身。所以'S'隐式映射到'S'。但是,您的字典也会将“P”映射到“S”。

    如果这个问题得到解决,逆转加密的关键点当然是@Boris Lipschitz 指出的字典逆转。

    但是,您的代码并不容易支持这一点。为什么?因为您的 encrypt_file 方法确实很多。它打开一个文件,它加密并保存一个文件。太多了!一个方法应该只做一个的事情。考虑这种方法:

    
    def encrypt(content, mapping):
        result = ""
        for char in content:
            char = char.upper()
            if char in mapping.keys():
                new_char = mapping[char]
                result += new_char
            else:
                result += char
        return result
    
    
    with open('texttoencrypt.txt', 'r') as f:
        content = f.read()
        print(content)
        encrypted = encrypt(content, dictionary)
    
    print(encrypted)
    
    reversed_mapping = {v: k for k, v in dictionary.items()}
    decrypted = encrypt(encrypted, reversed_mapping)
    
    print(decrypted)
    

    这几乎就是您的代码,但我将所有与加密算法无关的内容从 encrypt 方法中移出。现在它可以很容易地重复使用来解密! (您可以通过编写 result += mapping.get(char, char) 来进一步改进这一点,但我想保持接近您的原始代码。

    Boris Lipschitz 的论点是完全正确的,但是:不要重新发明轮子。只需使用 maketrans/transform 解决方案 :)

    【讨论】:

    • 虽然我完全同意将其分离为一个函数,但除了正确编码之外,还需要学习的是不要重新发明轮子。 translate 方法几乎完全符合这里的要求,而 IMO 应该使用它。
    • 这取决于。如果它以任何方式是“生产代码”,你显然是对的!如果这是为了某种家庭作业,仅使用“import caesar_cipher”解决任务可能有点让人不知所措:)
    • 有点让我想知道下一个练习是否会是“假设消息是英文的,编写代码来尝试破解替换密码”,哈哈。是的,我同意。
    • 这两个都太有帮助了!!谢谢你们俩。当我启动该程序时,我的第一个意图是读取、加密并保存到第二个文件,我没有具体的方法。当我引入方法时,我有点不知道从哪里开始。我会根据你的建议和例子做一些修改,看看我能做什么。谢谢!
    • ''.join(chr((ord(c)-ord('A')+shift)%26+ord('A')) if c>='A' and c<='Z' else c for c in str) 这实际上会在一行中为您完成 caesar,无需替换表,将 str 设置为您的 sting,转换为 3 用于加扰,23 用于解扰 ;-)(免责声明:试图模仿Python 大师在这里,我通常不会这样编码,lol)
    【解决方案2】:

    可以使用列表推导来反转字典,如下所示: reversed_dictionary = {(v,k) for k,v in dictionary.items()}。这假设您在原始文件中没有重复的值,而您本来就不应该有这些值。不过,不确定“打印出字典中的键”是什么意思。

    请注意,您最好使用已经存在的解决方案,即“翻译”方法。这是一个例子,它也发现了你的翻译表的问题:

    plain =     'ABCDEFGHIJKLMNOPQRVWXYZ'
    scrambled = 'DEFGHIJKLMNOPQRSTUYZABC'
    
    scramble = str.maketrans(plain, scrambled)
    descramble = str.maketrans(scrambled, plain)
    
    s1 = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"
    s2 = s1.translate(scramble)
    s3 = s2.translate(descramble)
    
    print("Original:    %s" % s1)
    print("Scrambled:   %s" % s2)
    print("Descrambled: %s" % s3)
    

    【讨论】:

    • 如何让用户在回复中提及?我尝试了 @ 和 # ,然后用完了想法......
    • @LydiavanDyke - 你输入@,然后是用户的第一个字母,它可以让你标记一个。
    • 嗯。在评论部分,我还看到一个文本块说同样的事情。但@Boris 目前不起作用。
    猜你喜欢
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多