0

我的 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.'
4

3 回答 3

3
caeser.encrypt(source)

进入

caeser.encrypt(source.read())

source是一个文件对象——这个代码“工作”(不加密任何东西)的事实很有趣——结果是你list()在迭代之前调用了源代码,这把它变成了文件中的行列表。而不是通常的结果list(string)是字符列表。因此,当它尝试加密每个字符时,它会发现一整行与您设置的任何替换都不匹配。

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

关于您的代码的一些随机注释(可能是您没有要求的吹毛求疵,呵呵)

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

编辑:如果有人想知道这些文件函数做了什么以及它们为什么工作,他们会raw_input()在一个 while 循环中调用,直到有一个合适的文件可以返回。openFileWriteRobust()有一个参数是默认值,以防用户不输入任何内容。代码链接在 OP 帖子上。

于 2013-04-07T21:03:30.490 回答
1

几点:

  • 使用上下文管理器 ( with) 可确保文件在读取或写入后关闭。
  • 由于凯撒密码是一种替换密码,其中移位参数是密钥,因此不需要单独的encrypt成员decrypt函数:它们是相同的,但“密钥”被否定。
  • 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编码器。

于 2013-04-07T22:26:32.320 回答
0

对我来说,source在调用openFileReadRobust(). 我不知道规范,openFileReadRobust()但似乎它不知道要打开哪个文件,除非有一个文件名作为参数给出,而且没有。

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

我建议打印出来sourceplaintextplain确保它们的值符合您的期望。

顺便openFileReadRobust()说一句,如果该函数可以为无意义的参数值返回无意义的值,那么该函数似乎对我没有多大帮助。我非常喜欢我的函数在这种情况下立即抛出异常。

于 2013-04-07T20:49:06.187 回答