凯撒密码(与其他人不同)

时间:2013-02-24 03:07:15

标签: python encryption

嘿伙计们,所以我试图按照这些说明制作一个密码:

  1. 打印标题。
  2. 提示用户输入带有加密消息的文件名称,即解码 key(移位号),以及存储解密消息的文件名。
  3. 从文件中读取加密邮件。
  4. 使用解码密钥移动加密邮件中的每个字符 生成与解密消息对应的新字符串的适当数字。
  5. 将解密的邮件保存在第二个文件中。
  6. 在屏幕上打印已加密和已解密的消息。 我不允许使用ord()或chr()函数。
  7. 真正令我困惑的是加密和解密文件部分。我真的不知道如何为此编码。

    我对此很新,所以任何帮助都会非常感激。 提前谢谢。

2 个答案:

答案 0 :(得分:4)

注意:听起来你可能正在做这个作为学校作业。我高度建议您仅将下面的代码用作示例,而不是完整的解决方案。我不喜欢有关于你的任务的抄袭问题,我相信你的教授/老师对谷歌以前的工作知识渊博。祝你的任务顺利!

我写了一个快速的例子,说明我如何尝试解决你的问题。该示例有一些已知问题:

  1. 它不涉及大写字母。 (除了将它们转换为小写的对应物。)
  2. 它不处理标点符号或非字母数字字符。 (数字,空格或行结尾。)
  3. 没有错误检查。
  4. 如果您尝试转换数字< -25它会惹你生气。
  5. 可能需要解决的最大问题是不使用ord()chr()的限制。我通过创建自己的字母到数字的转换列表绕过了这个限制,反之亦然。一个棘手的角落案例,以确保你处理如果移位移动转换范围之外的字母[0,25]会发生什么。

    作为旁注,如果要解密文件,可以简单地将其打开为纯文本,并使用负偏移量,其绝对值等于加密偏移量。或者用简单的英语,如果你使用参数:

    infile = clear.txt, offset = 1, outfile = encrypted.txt
    

    要解密,您可以使用:

    infile = encrypted.txt, offset = -1, outfile = decrypted.txt   
    

    <强> caesarcipher.py

    import itertools
    
    letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
               'r','s','t','u','v','w','x','y','z']
    numbers = range(26) # Numbers 0 - 25
    lettersToNumbers = dict(zip(letters, numbers))
    numbersToLetters = dict(zip(numbers, letters))
    
    def printHeader():
        """ Print the program informational header """
        print """=======================================
    Welcome to CaesarCipher - The unbreakable
    Roman cipher.
    ======================================="""
    
    def convertToNumber(letter):
        """ Convert a letter to a number using our predefined conversion table
            @param letter: The letter to convert to an integer value
            @type letter: str
            @rtype: int
        """
        return lettersToNumbers[letter]
    
    def convertToLetter(number):
        """ Convert a number to a letter using our predefined conversion table
            @param number: The number to convert to a letter
            @type number: int
            @rtype: str
        """
        # If we shift outside of our range make sure to wrap
        if number > 25:
            return numbersToLetters[number%25]
        elif number < 0:
            return numbersToLetters[number+25]
        else:
            return numbersToLetters[number]
    
    def shiftUp(letter, shift):
        """ Shift letter up a given number of positions
            @param letter: The letter we're shifting
            @param shift: The number of positions to shift up
            @type letter: str
            @type shift: int
    
            @note: For simplicity we encode both capital and lowercase letters
                   to the same values
        """
        number = convertToNumber(letter.lower())
        number += shift
        return convertToLetter(number)
    
    def prompt():
        """ Prompt for user input
            @rtype: tuple of str, int, str
        """
        infile = raw_input("File to encrypt: ")
        offset = int(raw_input("Encoding number: "))
        outfile = raw_input("Encrypted file destination: ")
        return (infile, offset, outfile)
    
    def encrypt(infile, offset, outfile):
        """ Encrypt the file using the given offset """
        print "=== Plaintext input ==="
        printFile(infile)
        with open(infile) as red_file:
            with open(outfile, 'w') as black_file:
                for line in red_file:
                    for letter in line:
                        # Only convert alphabetic characters
                        if letter.isalpha():
                            black_file.write(shiftUp(letter, offset))
                        else:
                            black_file.write(letter)
        print "=== Ciphertext output ==="
        printFile(outfile)
    
    def printFile(path):
        """ Print the data in the given file """
        with open(path) as print_file:
            for line in print_file:
                print line
    
    printHeader()
    encrypt(*prompt()) # `*` unpacks the tuple returned by `prompt()` into 
                       # three separate arguments.
    

    <强>的test.txt

    abcdef
    ABCDEF
    This is some text I want to try and encrypt.
    

    示例运行:

    mike@test:~$ python caesarcipher.py 
    =======================================
    Welcome to CaesarCipher - The unbreakable
    Roman cipher.
    =======================================
    File to encrypt: test.txt
    Encoding number: 1
    Encrypted file destination: test.out 
    === Plaintext input ===
    abcdef
    
    ABCDEF
    
    This is some text I want to try and encrypt.
    
    === Ciphertext output ===
    bcdefg
    
    bcdefg
    
    uijt jt tpnf ufyu j xbou up usz boe fodszqu.
    

答案 1 :(得分:0)

既然你说文件位是你最大的问题,我假设函数如下:

def decaesar(message, shift):
   pass

以字符串为基础对你进行decyphering - 也就是说,它将加密的消息作为字符串,并将解密的消息作为字符串返回给你。如果您还没有写过,请先执行此操作,然后使用硬编码字符串对其进行测试。在此阶段忽略“加密和解密的文件”位 - 编程就是一次解决一个问题。

一旦你拥有了这个功能并且你对它的工作感到高兴,扩展你的程序来处理文件而不是字符串就像问:

  • 在给定文件名的情况下,我可以获取包含文件内容的字符串吗? ,相反,
  • 我可以将字符串写入具有给定名称的文件吗?

如果您可以使用“是”回答这两个问题,那么您可以通过这种方式扩展程序而无需更改decaesar函数 - 您的逻辑如下所示:

# Print header
encrypted_filename, decrypted_filename, shift = # get from user input
encrypted_message = # get the contents of encrypted_filename as a string
decrypted_message = decaesar(encrypted_message, shift)
# write decrypted_message to decrypted_filename
# print encrypted_message and decrypted_message

有用的是,Python的文件IO完全符合字符串和文件之间转换的原则。如果您有一个可供阅读的文件:

in_file = open(filename)

,然后返回值:

in_file.read()

正是回答第一点的字符串。同样,如果您打开了一个可写的文件:

out_file = open(文件名,'w') 。然后:

out_file.write(my_string)

会将my_string放入该文件中。

这意味着如果你已经拥有了decaeser函数,那么你可以将这些代码放到上面适当位置的伪代码中,并且你将拥有一个主要工作的解决方案。