Python中文件的凯撒密码加密

时间:2013-04-07 20:23:26

标签: python encryption

我的Caeser密码在shell中以字符串交互式工作,但是当我尝试进行单独的程序加密和解密时,我遇到了问题,我不知道输入是否被分成了列表与否,但我的加密函数中的if语句被绕过并默认为填充未加密列表的else语句。任何建议赞赏。我正在使用Goldwasser书中的FileUtilities.py。该文件在第11章中为http://prenhall.com/goldwasser/sourcecode.zip,但我认为问题不在于此,但谁知道。提前谢谢。

#CaeserCipher.py
class CaeserCipher:

def __init__ (self, unencrypted="", encrypted=""):
    self._plain = unencrypted
    self._cipher = encrypted
    self._encoded = ""

def encrypt (self, plaintext):
    self._plain = plaintext
    plain_list = list(self._plain)
    i = 0
    final = []

    while (i <= len(plain_list)-1):
        if plain_list[i] in plainset:
            final.append(plainset[plain_list[i]])
        else:
            final.append(plain_list[i])
        i+=1
    self._encoded = ''.join(final)
    return self._encoded

def decrypt (self, ciphertext):
    self._cipher = ciphertext
    cipher_list = list(self._cipher)
    i = 0
    final = []
    while (i <= len(cipher_list)-1):
        if cipher_list[i] in cipherset:
            final.append(cipherset[cipher_list[i]])
        else:
            final.append(cipher_list[i])
        i+=1
    self._encoded = ''.join(final)
    return self._encoded

def writeEncrypted(self, outfile):
    encoded_file = self._encoded
    outfile.write('%s' %(encoded_file))

#encrypt.py
from FileUtilities import openFileReadRobust, openFileWriteRobust
from CaeserCipher import CaeserCipher

caeser = CaeserCipher()

source = openFileReadRobust()
destination = openFileWriteRobust('encrypted.txt')
caeser.encrypt(source)
caeser.writeEncrypted(destination)
source.close()
destination.close()
print 'Encryption completed.'

3 个答案:

答案 0 :(得分:3)

caeser.encrypt(source)

caeser.encrypt(source.read())

source是一个文件对象 - 这个代码“工作”(通过不加密任何东西)的事实很有意思 - 事实证明你在迭代之前在源上调用list()并将其转换为文件中的行列表。而不是通常的list(string)结果,这是一个字符列表。因此,当它尝试加密每个字符时,它会找到与您设置的任何替换都不匹配的整行。

也像其他人指出的那样,你忘了在代码中包含plainset,但这并不重要。

关于你的代码的一些随机记录(可能是你没有要求的挑剔,嘿)

  • 你错了“Caesar”
  • 你正在使用在python中效率低下的习语(通常称为“非pythonic”),其中一些可能来自其他语言如C的经验。
    • 那些while循环可以是for item in string: - 字符串已经像你试图转换的字节列表一样工作。
    • 写入outfile的行可能只是outfile.write(self._encoded)
  • 两个函数都非常相似,几乎是复制粘贴的代码。尝试编写第三个函数,它共享两者的功能,但有两个“模式”,加密和解密。您可以根据模式使其在cipher_list或plain_list上工作,例如
  • 我知道你这是为了练习,但标准库包括these functions这种替换。包括电池!

编辑:如果有人想知道这些文件函数的功能及其工作原理,他们会在while循环中调用raw_input(),直到有合适的文件返回。 openFileWriteRobust()有一个参数,如果用户没有输入任何内容,则该参数是默认值。代码链接在OP帖子上。

答案 1 :(得分:1)

有些观点:

  • 使用上下文管理器(with)确保文件在读取或写入后关闭。
  • 由于caesar密码是替换密码,其中shift参数是密钥,因此不需要单独的encryptdecrypt成员函数:它们是相同的但是具有“密钥”否定。
  • writeEncrypted方法只是文件写入方法的包装器。因此,该类实际上只有两种方法,其中一种方法是__init__
  • 这意味着您可以轻松地用一个功能替换它。

考虑到这一点,您的代码可以替换为此;

import string

def caesartable(txt, shift):
    shift = int(shift)
    if shift > 25 or shift < -25:
        raise ValueError('illegal shift value')
    az = string.ascii_lowercase
    AZ = string.ascii_uppercase
    eaz = az[-shift:]+az[:-shift]
    eAZ = AZ[-shift:]+AZ[:-shift]
    tt = string.maketrans(az + AZ, eaz + eAZ)
    return tt

enc = caesartable(3) # for example. decrypt would be caesartable(-3)
with open('plain.txt') as inf:
    txt = inf.read()
with open('encrypted.txt', 'w+') as outf:
    outf.write(txt.translate(enc))

如果您使用的是13的班次,则可以使用内置的rot13编码器。

答案 2 :(得分:0)

对我来说,在source致电后openFileReadRobust()中会有任何内容,这一点并不明显。我不知道openFileReadRobust()的规范,但似乎它不知道要打开哪个文件,除非有作为参数给出的文件名,并且没有一个。

因此,我怀疑source为空,因此plain也是空的。

我建议打印出sourceplaintextplain,以确保他们的价值符合您的预期。

顺便说一句,如果openFileReadRobust()函数可以返回非感知参数值的非感知值,那么{{1}}函数似乎对我没有帮助。我非常喜欢我的函数在这种情况下立即抛出异常。