2016-12-05 7 views
-2

Hey Leute, wenn Sie sich meinen Code unten sehen, können Sie sehen, dass ich in der Lage war, ein Programm zu erstellen, das den Inhalt der Datei öffnen und in eine andere Datei speichern kann Ich muss den Schlüssel jedes Mal eingeben, aber was, wenn ich nicht weiß, dass sie Schlüssel sind, wie kann ich den Schlüssel berechnen, der die Frequenzanalyse verwendet.Caesar Chiffre ohne den Schlüssel zu kennen

import sys 

def decrypt(cipher, key): 

plain = "" 
for index in range(len(cipher)): 
    if cipher[index].isalpha(): 

     if cipher[index].isupper(): 
      plain = plain + chr((ord(cipher[index]) - 64 - key) % 26 + 64) 


     elif cipher[index].islower(): 
      plain = plain + chr((ord(cipher[index]) - 96 - key) % 26 + 96) 

    else: 
      plain = plain + cipher[index] 

return plain 

in_filename = sys.argv[1] 
key = int(sys.argv[2]) 
out_filename = sys.argv[3] 

with open(in_filename, "r") as f: 
    encrypted = f.read() 

decrypted = decrypt(encrypted, key) 

with open(out_filename, "w+") as f: 
    f.write(decrypted) 
+4

Hilfe mit was genau ?? –

+0

Entschuldigung, wir brauchen mehr Informationen, um dir zu helfen ... hast du schon etwas Code, den du posten kannst? – Dadep

+0

Wenn Sie Text aus einer bekannten Sprache entschlüsseln, können Sie einfach jeden möglichen Schlüssel ausprobieren und sehen, wie viele der resultierenden Wörter in einer Wortliste dieser Sprache sind. –

Antwort

1

Ein Caesar-Cipher ist eine lineare Substitutionsziffer. Erklärung:

Haben Sie p seien Sie Ihr Klartext. Haben k unser numerischer Schlüssel sein (< 26 wegen dieser Erklärung). Haben c ein Zeichen in p. Haben I (c) sein der Index von c in p. Haben fc (i) eine Funktion sein, die einen Index i zu seinem Buchstaben im Alphabet abbildet. Haben e (c) das "verschlüsselte" Zeichen von c sein.

Dann:

e (c) = fc (I (c) + k)

oder in Klartext: Jedes Zeichen wird durch den Wert von k verschoben. Es ist daher eine lineare Substitution, da es immer um den gleichen Betrag verschoben wird und die Zeichen ersetzt werden.

Das Problem mit diesem Verschlüsselungsalgorithmus ist, dass Sie nicht wirklich den Klartext verschlüsseln oder Entropie hinzufügen. (In harten Worten, die Caesar-Cipher ist näher an einer Codierung als an einer Verschlüsselung).

Da wissen wir, dass alle übereinstimmenden Buchstaben in unserem Chiffre-Text für die genau gleiche Klartext-Zeichen ersetzen.

Das bedeutet, Sie können statistische Analysen auf Ihrem Cipher-Text durchführen und einfach die Briefverteilung analysieren. Verschiedene Töne/Buchstaben treten unterschiedlich oft auf.

Also, wie wenden wir diese Technik an?

Aufgrund Ihres Namens würde ich annehmen, dass Sie Deutscher sind und ich nehme an, dass Ihr Chiffre-Text auch ist.

In Deutsch, die am häufigsten verwendeten Buchstaben sind E und I.

Wir sind fast da!

Jetzt können Sie einfach den häufigsten Buchstaben in Ihrem Chiffre-Text finden und den Unterschied zwischen diesem Buchstaben und E (Differenz zwischen ihren Indizes, natürlich) berechnen. Das wird dir den geheimen Schlüssel geben!

Hier ist ein Codebeispiel:

""" 
This module aims to break Caesar-ciphers from German plaintext 
based  on statistics of letter distribution. 

The caesar cipher is a character substitution algorithm. 
Bob chooses a number as the key n. 
Bob then shifts every character of the plain-text by n, cycling 
through the entire alphabet. 

e.g.: if n = 3: "ABC" -> "DEF". 

Since it has a very small keyspace (26^1), it can be easily broken, 
and Mallory could even guess or bruteforce the key. 
(Note: You could choose a number higher than 26. However, this won't 
increase your keyspace since any number x will 
be reduced to 1-26. See: (x - (26*(x // 26)). 

Common letters in the german language are (in descending order): 
"E","N","I","S","R" (subject to verification) 

The statistical approach works well for long sentences since one has 
a greater samplesize for distribution analysis. 
If two or more letters appear the same amount of times, you have to 
check which key is actually correct, either 
by simply reading the outputs or running them against a 
distribution_dict of that language. 

""" 

ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
SPECIAL_CHARS = " ,.-;:_?!=" 

def encrypt(plain_text, key): 
    """ 
    Encrypts plaintext using a caesar. 

    :param plain_text: The plaintext 
    :param key: The key (Integer) 
    :return: The cipher-text 
    """ 
    cipher_text = "" 
    for letter in plain_text: 
     if letter in SPECIAL_CHARS: 
      cipher_text += letter 
      continue 
     index = ALPHABET.find(letter.upper()) 
     new_index = flatten(index + key) 
     cipher_text += ALPHABET[new_index] 
    return cipher_text 

def decrypt(cipher_text, key=None): 
    """ 
    This function decrypts plaintext. If no key is specified, it 
    will be found using distribution analysis. 
    :param cipher_text: The cipher-text 
    :param key: The key 
    :return: the plain-text 
    """ 
    if key is None: 
     key = find_key_from_cipher(cipher_text) 

    plain_text = "" 
    for letter in cipher_text: 
     #Skipping special characters (incomplete solution) 
     if letter in SPECIAL_CHARS: 
      plain_text += letter 
      continue 
     index = ALPHABET.find(letter.upper()) 
     new_index = flatten(index - key) 
     plain_text += ALPHABET[new_index] 

    return plain_text 

def flatten(number) : 
    """ 
    Flattens the key back to be in range(1,26) 
    :param number: 
    :return: 
    """ 
    return number - (26*(number//26)) 


def find_key_from_cipher(cipher_text): 
    index_of_most_common_letter = 4 #Index of 'e' 

    #Calculate distribution 
    distribution_dict = analyse_letter_distribution(cipher_text) 
    #Get common letters 
    common_letters = sorted(distribution_dict, key=distribution_dict.get, reverse=True) 

    #Use most common letter to get key 
    key = ALPHABET.find(common_letters[0].upper()) - index_of_most_common_letter 
    return key 

def analyse_letter_distribution(cipher_text): 
    distribution_dict = {} 
    for letter in cipher_text: 
     if letter in SPECIAL_CHARS: 
      continue 
     if letter not in distribution_dict: 
      distribution_dict[letter] = 1 
     else: 
      distribution_dict[letter] += 1 
    if len(distribution_dict.values()) != len(distribution_dict.values()): 
     print("Multiple letters appear the same amount of times! Uh oh.") 
    return distribution_dict 


    if __name__ == "__main__": 
     secret = encrypt("This sentence is encrypted. Encryption is broken  by using awesome encryption algorithms!",5) 
     print(decrypt(secret)) 

Eine letzte Anmerkung: Da es sich um eine statistische Analyse ist dieser Ansatz funktioniert am besten, wenn das aufgenommene Chiffre-Text lang ist.

Eine letzte letzte Anmerkung: Diese Beschreibung ist ein wenig unvollständig (und die Formatierung sieht hässlich aus, ich bin auf dem Handy.) Ich empfehle dieses german book von Klaus Schmeh für weitere Lektüre.

+0

Ich werde den Code oben bearbeiten es ist in der Lage, eine Datei zu öffnen entschlüsseln den Text aus dieser Datei und speichern Sie es in eine andere Datei –

+0

Und jetzt müssen Sie nur ** fonts_key_from_cipher 'kopieren und einfügen und seine enthaltenen Symbole und ändern Sie Ihren Aufruf zu entschlüsseln (verschlüsselt , find_key_from_cipher (verschlüsselt)) '. –

+0

können Sie meinen Code oben bearbeiten, damit ich nichts wieder vermassle –

Verwandte Themen