【问题标题】:File Encryption and Decryption using a given key使用给定密钥的文件加密和解密
【发布时间】:2017-08-18 02:17:40
【问题描述】:

我有一个学校问题,我似乎无法解决。基本上,我正在介绍面向对象的编程课程,所以我只需要尽可能基本地完成这个,而不使用我还没有学过的任何花哨的东西。目前正在学习字典和集合,我需要使用一个写有代码的字典来加密一个在一行上有一个长字符串的文档。

所以我需要一部分来阅读字典并打开包含字符串的文本文件。

"The course Introduction to Object Oriented Programming uses the Python programming language."

然后我需要使用此字典中的代码对其进行加密,并将加密后的字符串版本写入另一个名为 encrypt.txt 的文本文件。

CODE = {'A': ')', 'a': '0', 'B': '(', 'b': '9', 'C': '*', 'c': '8',
    'D': '&', 'd': '7', 'E': '^', 'e': '6', 'F': '%', 'f': '5',
    'G': '$', 'g': '4', 'H': '#', 'h': '3', 'I': '@', 'i': '2',
    'J': '!', 'j': '1', 'K': 'Z', 'k': 'z', 'L': 'Y', 'l': 'y',
    'M': 'X', 'm': 'x', 'N': 'W', 'n': 'w', 'O': 'V', 'o': 'v',
    'P': 'U', 'p': 'u', 'Q': 'T', 'q': 't', 'R': 'S', 'r': 's',
    'S': 'R', 's': 'r', 'T': 'Q', 't': 'q', 'U': 'P', 'u': 'p',
    'V': 'O', 'v': 'o', 'W': 'N', 'w': 'n', 'X': 'M', 'x': 'm',
    'Y': 'L', 'y': 'l', 'Z': 'K', 'z': 'k', '!': 'J', '1': 'j',
    '@': 'I', '2': 'i', '#': 'H', '3': 'h', '$': 'G', '4': 'g',
    '%': 'F', '5': 'f', '^': 'E', '6': 'e', '&': 'D', '7': 'd',
    '*': 'C', '8': 'c', '(': 'B', '9': 'b', ')': 'A', '0': 'a',
    ':': ',', ',': ':', '?': '.', '.': '?', '<': '>', '>': '<',
    "'": '"', '"': "'", '+': '-', '-': '+', '=': ';', ';': '=',
    '{': '[', '[': '{', '}': ']', ']': '}'}

这是我到目前为止的代码。任何帮助将不胜感激,外行的解释也将不胜感激。

CODE = {'A': ')', 'a': '0', 'B': '(', 'b': '9', 'C': '*', 'c': '8',
    'D': '&', 'd': '7', 'E': '^', 'e': '6', 'F': '%', 'f': '5',
    'G': '$', 'g': '4', 'H': '#', 'h': '3', 'I': '@', 'i': '2',
    'J': '!', 'j': '1', 'K': 'Z', 'k': 'z', 'L': 'Y', 'l': 'y',
    'M': 'X', 'm': 'x', 'N': 'W', 'n': 'w', 'O': 'V', 'o': 'v',
    'P': 'U', 'p': 'u', 'Q': 'T', 'q': 't', 'R': 'S', 'r': 's',
    'S': 'R', 's': 'r', 'T': 'Q', 't': 'q', 'U': 'P', 'u': 'p',
    'V': 'O', 'v': 'o', 'W': 'N', 'w': 'n', 'X': 'M', 'x': 'm',
    'Y': 'L', 'y': 'l', 'Z': 'K', 'z': 'k', '!': 'J', '1': 'j',
    '@': 'I', '2': 'i', '#': 'H', '3': 'h', '$': 'G', '4': 'g',
    '%': 'F', '5': 'f', '^': 'E', '6': 'e', '&': 'D', '7': 'd',
    '*': 'C', '8': 'c', '(': 'B', '9': 'b', ')': 'A', '0': 'a',
    ':': ',', ',': ':', '?': '.', '.': '?', '<': '>', '>': '<',
    "'": '"', '"': "'", '+': '-', '-': '+', '=': ';', ';': '=',
    '{': '[', '[': '{', '}': ']', ']': '}'}

def main():
    #Open the file you want to encrypt.
    infile = str(input('Enter the name of the input file: '))
    #read its contents
    dtext = open(infile, 'r')
    #read the line from the file
    dtext = dtext.readlines()

    #strip the newline
    #dtext = dtext.rstrip('\n')

    #call the encryptText function
    encryptText(dtext)

def encryptText(dtext):
    #enter the name of the file to write to
    outfile = str(input('Enter the name of the output file: '))
    #open the file to send encrypted text to
    etext = open(outfile, 'w')
    #set accumulator value
    count = 0
    #create a for loop to read each separate character
    for line in dtext:
        wordList = line.split()
        print(dtext, CODE[dtext])
    count += 1

main()

【问题讨论】:

  • 出了什么问题?我得到了TypeError: unhashable type: 'list' ...你看到的是这样的吗?
  • 是的,但我想我已经弄清楚了那部分,但现在我遇到了一个新错误... KeyError: ' '
  • 在我的解决方案中,我使用了dict.get(c,c),它试图获取映射的 c 但否则会传递原始文件。对于 ascii 文本,它不会对制表符和换行符之类的内容进行编码。
  • 旁注:这是str.translate完美案例。只需预处理CODE = str.maketrans(CODE)(修复键定义),然后通过您的表进行转换就是cipher = plain.translate(CODE)

标签: python dictionary encryption


【解决方案1】:

您需要逐个字符地加密,并且需要获取结果并将其重新构建为字符串。 str.join 将一系列字符转换为字符串,并且可以编写一个生成器来加密每个字符...将它们放在一起,您就有了解决方案。

CODE = {'A': ')', 'a': '0', 'B': '(', 'b': '9', 'C': '*', 'c': '8',
    'D': '&', 'd': '7', 'E': '^', 'e': '6', 'F': '%', 'f': '5',
    'G': '$', 'g': '4', 'H': '#', 'h': '3', 'I': '@', 'i': '2',
    'J': '!', 'j': '1', 'K': 'Z', 'k': 'z', 'L': 'Y', 'l': 'y',
    'M': 'X', 'm': 'x', 'N': 'W', 'n': 'w', 'O': 'V', 'o': 'v',
    'P': 'U', 'p': 'u', 'Q': 'T', 'q': 't', 'R': 'S', 'r': 's',
    'S': 'R', 's': 'r', 'T': 'Q', 't': 'q', 'U': 'P', 'u': 'p',
    'V': 'O', 'v': 'o', 'W': 'N', 'w': 'n', 'X': 'M', 'x': 'm',
    'Y': 'L', 'y': 'l', 'Z': 'K', 'z': 'k', '!': 'J', '1': 'j',
    '@': 'I', '2': 'i', '#': 'H', '3': 'h', '$': 'G', '4': 'g',
    '%': 'F', '5': 'f', '^': 'E', '6': 'e', '&': 'D', '7': 'd',
    '*': 'C', '8': 'c', '(': 'B', '9': 'b', ')': 'A', '0': 'a',
    ':': ',', ',': ':', '?': '.', '.': '?', '<': '>', '>': '<',
    "'": '"', '"': "'", '+': '-', '-': '+', '=': ';', ';': '=',
    '{': '[', '[': '{', '}': ']', ']': '}'}

def main():
    #Open the file you want to encrypt.
    infile = str(input('Enter the name of the input file: '))
    #read its contents
    dtext = open(infile, 'r')
    #read the line from the file
    dtext = dtext.readlines()

    #strip the newline
    #dtext = dtext.rstrip('\n')

    #call the encryptText function
    encryptText(dtext)

def encryptText(dtext):
    #enter the name of the file to write to
    outfile = str(input('Enter the name of the output file: '))
    #open the file to send encrypted text to
    etext = open(outfile, 'w')
    #set accumulator value

    #create a for loop to read each separate character
    for line in dtext:
        # encrypt character by character then join to a string
        encrypted = ''.join(CODE.get(c, c) for c in line)
        print(repr(line), repr(encrypted))
        etext.write(encrypted)
    etext.close()

main()

【讨论】:

  • 作为记录,鉴于这似乎是 Python 3,您可以大大简化。定义CODE 后,添加行CODE = str.maketrans(CODE) 将其转换为str.translate 友好dict,然后将geneexpr 和join 替换为encrypted = line.translate(CODE)。应该快得多,并且您正在使用最直接的工具来完成这项工作。
  • @ShadowRanger - 我同意有更好的方法和方法可以使这段代码更干净,但由于这是针对新手编程课程,我想尽可能少地打扰它。如果我正在教初学者课程并得到您的解决方案,我会考虑作弊 F!
  • 真的吗?我的意思是,如果您查找 str 方法,str.translate 基本上是在描述您如何使用与给定形式完全相同的 dict(好吧,它需要由 maketrans 修复才能使用序数作为键,但足够接近)。它实际上更容易被一个盲目寻找的新手找到,而不是一个已经知道“正确的方法”但以前从未遇到过该特定方法的经验丰富的程序员。
  • 我和 tdelaney 在一起,我试图让它尽可能简单,因为我们还没有学到很多东西。因为我真的很喜欢学习而不是被教导,所以对于这些实验室,我首先需要以最简单的方式学习它!不想作弊哈哈
  • 但是您的代码可以正常工作,但我认为我还没有学会如何使用 join,这是唯一的问题。
【解决方案2】:

字符串是不可变的。这意味着您无法在创建后编辑它们,这与数组形成鲜明对比。您必须构建一个新字符串才能加密您的文本。您可能还需要一次完成一个角色。由于您将 dtext 中的文件文本作为字符串,您可以像这样遍历原始字符串中的字符:

for i in range (0, len(dtext)):
    # add new character to string

(我把它拆开,所以你不能只是复制和粘贴)

您必须创建一个新字符串以将加密文本放在该 for 循环之外。

enc = ""

为了通过替换来加密值,如果它们在您定义的字典中,您可以一次将一个字符添加到该 for 循环中的加密字符串。有点意思

if (dtext[i] in CODE.keys()):
    enc += CODE[dtext[i]]

然后将新字符串写入文件即可。

python 中的字典实际上是一个可由键索引的数组。该键映射到给定值,就像数组索引映射到某个值一样。详情请见https://www.tutorialspoint.com/python/python_dictionary.htm

【讨论】:

  • 啊,我想我明白了!我现在试试看能不能拿到。我正在使用它并开始到达某个地方,但是您的方法更有意义。对于 dtext 中的行:对于行中的 ch:print(ch, CODE[ch])
【解决方案3】:

tdelaney 的回答是正确的,但我接受了它并将其制成更简单的版本。我改变了一点。这就是我所做的:

我没有加入空字符串,而是完全删除了该部分。我只是逐个字符地遍历整个字符串,然后像 tdelaney 一样,使用 get 方法来使用代码字典中的键。

CODE = {'A': ')', 'a': '0', 'B': '(', 'b': '9', 'C': '*', 'c': '8',
    'D': '&', 'd': '7', 'E': '^', 'e': '6', 'F': '%', 'f': '5',
    'G': '$', 'g': '4', 'H': '#', 'h': '3', 'I': '@', 'i': '2',
    'J': '!', 'j': '1', 'K': 'Z', 'k': 'z', 'L': 'Y', 'l': 'y',
    'M': 'X', 'm': 'x', 'N': 'W', 'n': 'w', 'O': 'V', 'o': 'v',
    'P': 'U', 'p': 'u', 'Q': 'T', 'q': 't', 'R': 'S', 'r': 's',
    'S': 'R', 's': 'r', 'T': 'Q', 't': 'q', 'U': 'P', 'u': 'p',
    'V': 'O', 'v': 'o', 'W': 'N', 'w': 'n', 'X': 'M', 'x': 'm',
    'Y': 'L', 'y': 'l', 'Z': 'K', 'z': 'k', '!': 'J', '1': 'j',
    '@': 'I', '2': 'i', '#': 'H', '3': 'h', '$': 'G', '4': 'g',
    '%': 'F', '5': 'f', '^': 'E', '6': 'e', '&': 'D', '7': 'd',
    '*': 'C', '8': 'c', '(': 'B', '9': 'b', ')': 'A', '0': 'a',
    ':': ',', ',': ':', '?': '.', '.': '?', '<': '>', '>': '<',
    "'": '"', '"': "'", '+': '-', '-': '+', '=': ';', ';': '=',
    '{': '[', '[': '{', '}': ']', ']': '}'}

def main():
    #Open the file you want to encrypt.
    infile = str(input('Enter the name of the input file: '))
    #read its contents
    dtext = open(infile, 'r')
    #read the line from the file
    dtext = dtext.readlines()

    #call the encryptText function
    encryptText(dtext)

def encryptText(dtext):
    #enter the name of the file to write to
    outfile = str(input('Enter the name of the output file: '))
    #open the file to send encrypted text to
    etext = open(outfile, 'w')
    #create a for loop to read each separate character
    for line in dtext:
        # encrypt character by character then join to a string
        for c in line:
            encrypted = (CODE.get(c, c))
            etext.write(encrypted)
    #close the file
    etext.close()

main()

【讨论】:

  • 您知道,回答您自己的问题不是惯例。上次我这样做时,我被严重否决并且失去了相当多的代表。我不会对此做任何事情,b / c我认为这是有道理的。不过我想我会警告你的。
  • 哦,真的吗?对不起,我对这一切和这个网站都是新手。不过,我很感谢您的反馈。
  • @thedevelop3r 可以回答您自己的问题。您只需要了解它需要是对所提出问题的完整答案。这包括一些代码和错误的描述。另外,抄袭别人的答案也是不行的。
  • @Classicalclown 请尽量小心您发布代码的方式。我正确地缩进了你的代码,但你必须学习如何自己做,比如标记有问题的代码并按 Ctrl+K。此外,您可以编辑自己的答案。您不必删除答案并发布新答案。
  • 为什么我在回答关于减少三倍数的问题时被否决了?是b/c吗?我回答得好像我不是问它的那个人吗? stackoverflow.com/q/36818054/3281844
猜你喜欢
  • 1970-01-01
  • 2014-10-24
  • 2011-05-09
  • 1970-01-01
  • 2020-04-23
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多