我正在尝试实现Vigenere的密码。我希望能够混淆文件中的每个字符,而不仅仅是字母字符。
我想我错过了不同类型编码的东西。我已经做了一些测试用例,并且在最终结果中一些字符被严重替换。
这是一个测试用例:
,.-'`1234678abcde ^ * {} “¿?!” ·$%&安培; / \º
端
这是我得到的结果:
).- 4`1234678abcde ^ * {} “??!” 7 $%&安培; /:
端
正如你所看到的,','正在被')'以及其他一些角色严重替换。
我的猜测是其他的(例如'''被'?'替换)来自不在[0,127]范围内的原始字符,所以它们的正常情况会发生变化。但我不明白为什么','失败了。
我的目的是混淆CSV文件,因此','问题是我主要关注的问题。
在下面的代码中,我使用模数128,但我不确定这是否正确。要执行它,将名为“OriginalFile.txt”的文件放在与内容相同的文件夹中以加密并运行脚本。将生成两个文件,Ciphered.txt和Deciphered.txt。
"""
Attempt to implement Vigenere cipher in Python.
"""
import os
key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
fileOriginal = "OriginalFile.txt"
fileCiphered = "Ciphered.txt"
fileDeciphered = "Deciphered.txt"
# CIPHER PHASE
if os.path.isfile(fileCiphered):
os.remove(fileCiphered)
keyToUse = 0
with open(fileOriginal, "r") as original:
with open(fileCiphered, "a") as ciphered:
while True:
c = original.read(1) # read char
if not c:
break
k = key[keyToUse]
protected = chr((ord(c) + ord(k))%128)
ciphered.write(protected)
keyToUse = (keyToUse + 1)%len(key)
print("Cipher successful")
# DECIPHER PHASE
if os.path.isfile(fileDeciphered):
os.remove(fileDeciphered)
keyToUse = 0
with open(fileCiphered, "r") as ciphered:
with open(fileDeciphered, "a") as deciphered:
while True:
c = ciphered.read(1) # read char
if not c:
break
k = key[keyToUse]
unprotected = chr((128 + ord(c) - ord(k))%128) # +128 so that we don't get into negative numbers
deciphered.write(unprotected)
keyToUse = (keyToUse + 1)%len(key)
print("Decipher successful")
答案 0 :(得分:1)
假设:您正在尝试使用Vigenere加密的单元格内容生成新的有效CSV,而不是加密整个文件。
在这种情况下,您应该查看csv
模块,该模块将为您正确读取和写入CSV文件(包括值中包含逗号的单元格,这可能在您加密单元格后发生#39 ; s内容,如你所见)。简而言之,您可以执行以下操作:
with open("...", "r") as fpin, open("...", "w") as fpout:
reader = csv.reader(fpin)
writer = csv.writer(fpout)
for row in reader:
# row will be a list of strings, one per column in the row
ciphered = [encipher(cell) for cell in row]
writer.writerow(ciphered)
使用csv
模块时,您应该了解" dialects"的概念。 - 不同程序(通常是类似电子表格的东西,想想Excel)处理CSV数据的方式。 csv.reader()
通常可以很好地推断出输入文件中的方言,但您可能需要告诉csv.writer()
输出文件需要什么方言。您可以使用csv.list_dialects()
获取内置方言列表,也可以通过创建自定义Dialect
对象来制作自己的方言。