2016-05-06 8 views
0

Ich versuche, Vigenere's Cipher zu implementieren. Ich möchte in der Lage sein, jedes einzelne Zeichen in einer Datei zu verschleiern, nicht nur alphabetische Zeichen.Vigenere Cipher in Python Bug

Ich denke, ich vermisse etwas mit den verschiedenen Arten der Codierung. Ich habe einige Testfälle gemacht und einige Zeichen werden im Endergebnis schlecht ersetzt.

Dies ist ein Testfall:

, .-'`1234678abcde^* {} "?! ¿" · $% &/\ º

Ende

Und dies ist das Ergebnis erhalte ich:

) .- 4`1234678abcde^* {} "??!" 7 $% & /:

Ende

Wie Sie sehen können, ‚‘ ersetzt schlecht mit ‚)‘ sowie einigen anderen Zeichen wird.

Meine Vermutung ist, dass die anderen (z. B. "¿" durch "?" Ersetzt werden) von dem ursprünglichen Zeichen stammen, das nicht im Bereich von [0, 127] liegt. Aber ich verstehe nicht, warum ',' versagt.

Meine Absicht ist es, CSV-Dateien zu verschleiern, also ist das ',' Problem das, worüber ich hauptsächlich besorgt bin.

Im folgenden Code verwende ich Modulo 128, aber ich bin mir nicht sicher, ob das korrekt ist. Um es auszuführen, legen Sie eine Datei mit dem Namen "OriginalFile.txt" in den gleichen Ordner mit dem Inhalt zum Chiffrieren und führen Sie das Skript aus. Zwei Dateien werden generiert, Ciphered.txt und 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") 
+1

(Welcher Schlüssel gab Ihnen die Beispielausgabe?) Auch wenn der Bereich auf 128 beschränkt ist, treten Probleme auf, weil die Zeichen "vor" dem Leerzeichen ebenfalls etwas Besonderes sind. Die beste Schleife um den 'einfachen' Teil von ASCII: nur die Ordinalzahlen von 32 bis 126. – usr2564301

+0

Für das Komma: willst du es * ignorieren * und wie gewohnt codieren, oder willst du * sie * beibehalten und nur richtig codieren? CSV-Einträge?(In diesem Fall solltest du darauf achten ** nicht ** etwas zu einem Komma zu kodieren!) – usr2564301

+1

@RadLexus Ich möchte das Komma auch codieren. Ich möchte nicht, dass ein Angreifer seine CSV-Datei kennt. Vielleicht muss ich ein wenig Abhilfe schaffen bei dem, was Sie sagen [32, 126]. Ich werde es versuchen und bald aktualisieren. – Guimo

Antwort

1

Annahme: Sie versuchen, eine neue, gültige CSV mit dem Inhalt von Zellen über Vigenere chiffriert zu produzieren, nicht die ganze Datei zu verschlüsseln.

In diesem Fall sollten Sie das csv Modul überprüfen, die richtig behandelt das Lesen und Schreiben von CSV-Dateien für Sie (einschließlich Zellen, die Kommas in dem Wert enthalten, die passieren könnte, nachdem Sie den Inhalt einer Zelle chiffrieren, wie Sie sehen,). Ganz kurz, können Sie so etwas wie tun:

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) 

Wenn das csv Modul verwenden, sollten Sie sich bewusst sein, der Begriff „dialects“ - Möglichkeiten, die verschiedene Programme (in der Regel tabellenähnliche Dinge, denken Excel) behandeln CSV Daten. csv.reader() funktioniert in der Regel gut, um den Dialekt abzuleiten, den Sie in der Eingabedatei haben, aber Sie müssen möglicherweise csv.writer() mitteilen, welchen Dialekt Sie für die Ausgabedatei haben möchten. Sie können die Liste der integrierten Dialekte mit csv.list_dialects() abrufen, oder Sie können Ihre eigenen erstellen, indem Sie ein benutzerdefiniertes Dialect Objekt erstellen.