我正在尝试通读文件并使用我的函数加密邮件。我只想加密单词,别忘了其他一切。读取的文件称为plain.txt,我想在名为newPlain.txt的新文件中对其进行加密。此外,我需要证明密码需要多少次转移。
这是我的功能:
# k is how many shifts you want
def CaeserCipher(string, k):
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
lower = 'abcdefgihjklmnopqrstuvwxyz'
newCipher = ''
for letter in string:
if letter in upper:
if upper.index(letter) + k > 25:
indexPosition = (upper.index(letter) + k) - 26
newCipher = newCipher + upper[indexPosition]
else:
indexPosition = upper.index(letter) + k
newCipher = newCipher + upper[indexPosition]
elif letter in lower:
if lower.index(letter) + k > 25:
indexPosition = (lower.index(letter) + k) - 26
newCipher = newCipher + lower[indexPosition]
else:
indexPosition = lower.index(letter) + k
newCipher = newCipher + lower[indexPosition]
return newCipher
这是我到目前为止所做的:
# main file
# reading file and encrypting text
f = open('plain.txt', "r+")
for line in f:
newLine = CaeserCipher(line, 3)
line.replace(line, newLine)
f.close()
我想将其分解为一个列表吗?但如果是这样的话,我怎么能把它放回同一个地方呢?如果有人对如何解决这个问题有一些想法,我将不胜感激。
plain.txt :(它不必以字母字符开头,也可以以空格开头,或任何不是字母的东西。
您好,我的名字是Ed。
你好吗?
来自Ed
答案 0 :(得分:2)
如果我是你,我会抓住单个单词并将它们映射到CaeserCipher
(正确命名为caesercipher
,仅根据PEP-8使用CapWords
作为类。这样做的原因是你的第一个要点:"我只想加密单词而不管其他一切。"因此,一个小的地图/滤镜动作听起来不错。
# def isWord(word):
# return all(ch.isalpha() for ch in word)
# oops I forgot that str.isalpha handles whole strings and not
# just characters. This is useless.
with open('plain.txt') as inf and open('encrypted.txt','w') as outf:
for line in inf:
line = [caesercipher(word) if word.isalpha() else word for word in line.strip().split()]]
outf.write(' '.join(line)+"\n")
或者,您可以重新定义caesercipher
,以便它不会触及非单词。
def caesercipher(string, k):
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
lower = 'abcdefgihjklmnopqrstuvwxyz'
if not string.isalpha():
return string
else:
# apply your cipher, which honestly should be something using a deque
# rotation building a str.translate mapping, but we'll keep it simple
# for now. Let me know if you want more info on that though.
然后跳过我发布的第一个代码块中line = [caesercipher(word) ...
语句中的检查。
可选:DEQUE REPLACEMENT
deque
基本上是一个循环列表。您rotate
deque(['1','2','3']).rotate(1) == deque(['3','1','2'])
可以from collections import deque
from copy import copy # just to save time
def caesercipher(string, k):
upper = deque("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
lower = deque("abcdefghijklmnopqrstuvwxyz")
resultupper = copy(upper)
resultupper.rotate(-k)
resultlower = copy(lower)
resultlower.rotate(-k)
dict_for_trans = dict(zip(upper,resultupper))
dict_for_trans.update(dict(zip(lower,resultlower)))
transdict = str.maketrans(dict_for_trans)
return string.translate(transdict)
。您可以使用它来构建一个非常高效的Caeser密码,如下所示:
str.translate
这个方法的好处是list.index
非常快,而且你提供的字典确保除了你个人定义的内容之外什么都不会被触及。这些k > 26
调用都不会永远占用,一切都是快速完成的。它也很有用,因为对于caesercipher("abc",27) -> 'bcd'
,它仍然有用! {{1}}
答案 1 :(得分:1)
您可以遍历这些行,只需确保在编写时添加换行符。
with open('plain.txt','r+') as plainFile:
lines = plainFile.read().splitlines()
with open('newPlain.txt', 'w') as newFile:
for line in lines:
newFile.write(CaesarCipher(line, 3) + "\n")
将遍历这些行,加密行,然后按顺序写入它们。